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