]> cygwin.com Git - cygwin-apps/cygutils.git/blame - src/ipc/semtool.c
Convert many programs to GPLv3+.
[cygwin-apps/cygutils.git] / src / ipc / semtool.c
CommitLineData
d4a28ab0
CW
1/*****************************************************************************
2 Excerpt from "Linux Programmer's Guide - Chapter 6"
3 (C)opyright 1994-1995, Scott Burkett
4 *****************************************************************************
5 MODULE: semtool.c
6 *****************************************************************************
7 A command line tool for tinkering with SysV style Semaphore Sets
8
9 *****************************************************************************/
bd695173 10/*
7156ebbc
CW
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
bd695173
CW
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
7156ebbc 22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
bd695173 23 *
7156ebbc 24 * See the COPYING file for full license information.
bd695173
CW
25 */
26
27#if HAVE_CONFIG_H
fe3a7d70 28# include "config.h"
bd695173 29#endif
d4a28ab0 30
d2b03e6a 31#include "common.h"
bd695173
CW
32
33#if HAVE_SYS_IPC_H
fe3a7d70 34# include <sys/ipc.h>
bd695173
CW
35#endif
36#if HAVE_SYS_SEM_H
fe3a7d70 37# include <sys/sem.h>
bd695173 38#endif
d4a28ab0 39
b5edac4c
CW
40/* cygserver doesn't define this constant where we
41 can get it, so just use the default configuration
42 value */
43#ifndef SEMMSL
44# define SEMMSL 60
45#endif
46
d4a28ab0 47/* arg for semctl system calls. */
fe3a7d70
CW
48union semun
49{
50 int val; /* value for SETVAL */
51 struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */
52 ushort *array; /* array for GETALL & SETALL */
53 struct seminfo *__buf; /* buffer for IPC_INFO */
d4a28ab0
CW
54 void *__pad;
55};
56
57#define SEM_RESOURCE_MAX 1 /* Initial value of all semaphores */
58
fe3a7d70
CW
59void opensem (int *sid, key_t key);
60void createsem (int *sid, key_t key, int members);
61void locksem (int sid, int member);
62void unlocksem (int sid, int member);
63void removesem (int sid);
64unsigned short get_member_count (int sid);
65int getval (int sid, int member);
66void dispval (int sid, int member);
67void changemode (int sid, char *mode);
68void usage (void);
69
70int
71main (int argc, char *argv[])
d4a28ab0 72{
fe3a7d70
CW
73 key_t key;
74 int semset_id;
75
76 if (argc == 1)
77 usage ();
78
79 /* Create unique key via call to ftok() */
80 key = ftok (".", 's');
81
82 switch (tolower (argv[1][0]))
83 {
84 case 'c':
85 if (argc != 3)
86 usage ();
87 createsem (&semset_id, key, atoi (argv[2]));
88 break;
89 case 'l':
90 if (argc != 3)
91 usage ();
92 opensem (&semset_id, key);
93 locksem (semset_id, atoi (argv[2]));
94 break;
95 case 'u':
96 if (argc != 3)
97 usage ();
98 opensem (&semset_id, key);
99 unlocksem (semset_id, atoi (argv[2]));
100 break;
101 case 'd':
102 opensem (&semset_id, key);
103 removesem (semset_id);
104 break;
105 case 'm':
106 opensem (&semset_id, key);
107 changemode (semset_id, argv[2]);
108 break;
109 default:
110 usage ();
111
112 }
113
114 return (0);
d4a28ab0
CW
115}
116
fe3a7d70
CW
117void
118opensem (int *sid, key_t key)
d4a28ab0 119{
fe3a7d70 120 /* Open the semaphore set - do not create! */
d4a28ab0 121
fe3a7d70
CW
122 if ((*sid = semget (key, 0, 0666)) == -1)
123 {
124 printf ("Semaphore set does not exist!\n");
125 exit (1);
126 }
d4a28ab0
CW
127
128}
129
fe3a7d70
CW
130void
131createsem (int *sid, key_t key, int members)
d4a28ab0 132{
fe3a7d70
CW
133 int cntr;
134 union semun semopts;
135
136 if (members > SEMMSL)
137 {
138 printf ("Sorry, max number of semaphores in a set is %d\n", SEMMSL);
139 exit (1);
140 }
141
142 printf ("Attempting to create new semaphore set with %d members\n",
143 members);
144
145 if ((*sid = semget (key, members, IPC_CREAT | IPC_EXCL | 0666)) == -1)
146 {
147 fprintf (stderr, "Semaphore set already exists!\n");
148 exit (1);
149 }
150
151 semopts.val = SEM_RESOURCE_MAX;
152
153 /* Initialize all members (could be done with SETALL) */
154 for (cntr = 0; cntr < members; cntr++)
155 semctl (*sid, cntr, SETVAL, semopts);
d4a28ab0
CW
156}
157
fe3a7d70
CW
158void
159locksem (int sid, int member)
d4a28ab0 160{
fe3a7d70
CW
161 struct sembuf sem_lock = { 0, -1, IPC_NOWAIT };
162
163 if (member < 0 || member > (get_member_count (sid) - 1))
164 {
165 fprintf (stderr, "semaphore member %d out of range\n", member);
166 return;
167 }
168
169 /* Attempt to lock the semaphore set */
170 if (!getval (sid, member))
171 {
172 fprintf (stderr, "Semaphore resources exhausted (no lock)!\n");
173 exit (1);
174 }
175
176 sem_lock.sem_num = member;
177
178 if ((semop (sid, &sem_lock, 1)) == -1)
179 {
180 fprintf (stderr, "Lock failed\n");
181 exit (1);
182 }
183 else
184 printf ("Semaphore resources decremented by one (locked)\n");
185
186 dispval (sid, member);
d4a28ab0
CW
187}
188
fe3a7d70
CW
189void
190unlocksem (int sid, int member)
d4a28ab0 191{
fe3a7d70
CW
192 struct sembuf sem_unlock = { member, 1, IPC_NOWAIT };
193 int semval;
194
195 if (member < 0 || member > (get_member_count (sid) - 1))
196 {
197 fprintf (stderr, "semaphore member %d out of range\n", member);
198 return;
199 }
200
201 /* Is the semaphore set locked? */
202 semval = getval (sid, member);
203 if (semval == SEM_RESOURCE_MAX)
204 {
205 fprintf (stderr, "Semaphore not locked!\n");
206 exit (1);
207 }
208
209 sem_unlock.sem_num = member;
210
211 /* Attempt to lock the semaphore set */
212 if ((semop (sid, &sem_unlock, 1)) == -1)
213 {
214 fprintf (stderr, "Unlock failed\n");
215 exit (1);
216 }
217 else
218 printf ("Semaphore resources incremented by one (unlocked)\n");
219
220 dispval (sid, member);
d4a28ab0
CW
221}
222
fe3a7d70
CW
223void
224removesem (int sid)
d4a28ab0 225{
fe3a7d70
CW
226 union semun semopts;
227 semopts.val = 0;
d4a28ab0 228
fe3a7d70
CW
229 semctl (sid, 0, IPC_RMID, semopts);
230 printf ("Semaphore removed\n");
d4a28ab0
CW
231}
232
fe3a7d70
CW
233unsigned short
234get_member_count (int sid)
d4a28ab0 235{
fe3a7d70
CW
236 union semun semopts;
237 struct semid_ds mysemds;
d4a28ab0 238
fe3a7d70 239 semopts.buf = &mysemds;
d4a28ab0 240
fe3a7d70
CW
241 /* Return number of members in the semaphore set */
242 return (semopts.buf->sem_nsems);
d4a28ab0
CW
243}
244
fe3a7d70
CW
245int
246getval (int sid, int member)
d4a28ab0 247{
fe3a7d70
CW
248 int semval;
249 union semun semopts;
250 semopts.val = 0;
d4a28ab0 251
fe3a7d70
CW
252 semval = semctl (sid, member, GETVAL, semopts);
253 return (semval);
d4a28ab0
CW
254}
255
fe3a7d70
CW
256void
257changemode (int sid, char *mode)
d4a28ab0 258{
fe3a7d70
CW
259 int rc;
260 union semun semopts;
261 struct semid_ds mysemds;
262
263 /* Get current values for internal data structure */
264 semopts.buf = &mysemds;
265
266 rc = semctl (sid, 0, IPC_STAT, semopts);
d4a28ab0 267
fe3a7d70
CW
268 if (rc == -1)
269 {
270 perror ("semctl");
271 exit (1);
272 }
d4a28ab0 273
fe3a7d70 274 printf ("Old permissions were %o\n", semopts.buf->sem_perm.mode);
d4a28ab0 275
fe3a7d70
CW
276 /* Change the permissions on the semaphore */
277 sscanf (mode, "%ho", &semopts.buf->sem_perm.mode);
d4a28ab0 278
fe3a7d70
CW
279 /* Update the internal data structure */
280 semctl (sid, 0, IPC_SET, semopts);
d4a28ab0 281
fe3a7d70 282 printf ("Updated...\n");
d4a28ab0
CW
283
284}
285
fe3a7d70
CW
286void
287dispval (int sid, int member)
d4a28ab0 288{
fe3a7d70
CW
289 int semval;
290 union semun semopts;
291 semopts.val = 0;
d4a28ab0 292
fe3a7d70
CW
293 semval = semctl (sid, member, GETVAL, semopts);
294 printf ("semval for member %d is %d\n", member, semval);
d4a28ab0
CW
295}
296
fe3a7d70
CW
297void
298usage (void)
d4a28ab0 299{
fe3a7d70
CW
300 fprintf (stderr, "semtool - A utility for tinkering with semaphores\n");
301 fprintf (stderr, "\nUSAGE: semtool (c)reate <semcount>\n");
302 fprintf (stderr, " (l)ock <sem #>\n");
303 fprintf (stderr, " (u)nlock <sem #>\n");
304 fprintf (stderr, " (d)elete\n");
305 fprintf (stderr, " (m)ode <mode>\n");
306 exit (1);
d4a28ab0 307}
This page took 0.05392 seconds and 5 git commands to generate.