]> cygwin.com Git - cygwin-apps/cygutils.git/blame - src/ipc/semtool.c
Make coding style consistent throughout
[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
CW
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
fe3a7d70 29# include "config.h"
bd695173 30#endif
d4a28ab0 31
d2b03e6a 32#include "common.h"
bd695173
CW
33
34#if HAVE_SYS_IPC_H
fe3a7d70 35# include <sys/ipc.h>
bd695173
CW
36#endif
37#if HAVE_SYS_SEM_H
fe3a7d70 38# include <sys/sem.h>
bd695173 39#endif
d4a28ab0 40
b5edac4c
CW
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
d4a28ab0 48/* arg for semctl system calls. */
fe3a7d70
CW
49union 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 */
d4a28ab0
CW
55 void *__pad;
56};
57
58#define SEM_RESOURCE_MAX 1 /* Initial value of all semaphores */
59
fe3a7d70
CW
60void opensem (int *sid, key_t key);
61void createsem (int *sid, key_t key, int members);
62void locksem (int sid, int member);
63void unlocksem (int sid, int member);
64void removesem (int sid);
65unsigned short get_member_count (int sid);
66int getval (int sid, int member);
67void dispval (int sid, int member);
68void changemode (int sid, char *mode);
69void usage (void);
70
71int
72main (int argc, char *argv[])
d4a28ab0 73{
fe3a7d70
CW
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);
d4a28ab0
CW
116}
117
fe3a7d70
CW
118void
119opensem (int *sid, key_t key)
d4a28ab0 120{
fe3a7d70 121 /* Open the semaphore set - do not create! */
d4a28ab0 122
fe3a7d70
CW
123 if ((*sid = semget (key, 0, 0666)) == -1)
124 {
125 printf ("Semaphore set does not exist!\n");
126 exit (1);
127 }
d4a28ab0
CW
128
129}
130
fe3a7d70
CW
131void
132createsem (int *sid, key_t key, int members)
d4a28ab0 133{
fe3a7d70
CW
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);
d4a28ab0
CW
157}
158
fe3a7d70
CW
159void
160locksem (int sid, int member)
d4a28ab0 161{
fe3a7d70
CW
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);
d4a28ab0
CW
188}
189
fe3a7d70
CW
190void
191unlocksem (int sid, int member)
d4a28ab0 192{
fe3a7d70
CW
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);
d4a28ab0
CW
222}
223
fe3a7d70
CW
224void
225removesem (int sid)
d4a28ab0 226{
fe3a7d70
CW
227 union semun semopts;
228 semopts.val = 0;
d4a28ab0 229
fe3a7d70
CW
230 semctl (sid, 0, IPC_RMID, semopts);
231 printf ("Semaphore removed\n");
d4a28ab0
CW
232}
233
fe3a7d70
CW
234unsigned short
235get_member_count (int sid)
d4a28ab0 236{
fe3a7d70
CW
237 union semun semopts;
238 struct semid_ds mysemds;
d4a28ab0 239
fe3a7d70 240 semopts.buf = &mysemds;
d4a28ab0 241
fe3a7d70
CW
242 /* Return number of members in the semaphore set */
243 return (semopts.buf->sem_nsems);
d4a28ab0
CW
244}
245
fe3a7d70
CW
246int
247getval (int sid, int member)
d4a28ab0 248{
fe3a7d70
CW
249 int semval;
250 union semun semopts;
251 semopts.val = 0;
d4a28ab0 252
fe3a7d70
CW
253 semval = semctl (sid, member, GETVAL, semopts);
254 return (semval);
d4a28ab0
CW
255}
256
fe3a7d70
CW
257void
258changemode (int sid, char *mode)
d4a28ab0 259{
fe3a7d70
CW
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);
d4a28ab0 268
fe3a7d70
CW
269 if (rc == -1)
270 {
271 perror ("semctl");
272 exit (1);
273 }
d4a28ab0 274
fe3a7d70 275 printf ("Old permissions were %o\n", semopts.buf->sem_perm.mode);
d4a28ab0 276
fe3a7d70
CW
277 /* Change the permissions on the semaphore */
278 sscanf (mode, "%ho", &semopts.buf->sem_perm.mode);
d4a28ab0 279
fe3a7d70
CW
280 /* Update the internal data structure */
281 semctl (sid, 0, IPC_SET, semopts);
d4a28ab0 282
fe3a7d70 283 printf ("Updated...\n");
d4a28ab0
CW
284
285}
286
fe3a7d70
CW
287void
288dispval (int sid, int member)
d4a28ab0 289{
fe3a7d70
CW
290 int semval;
291 union semun semopts;
292 semopts.val = 0;
d4a28ab0 293
fe3a7d70
CW
294 semval = semctl (sid, member, GETVAL, semopts);
295 printf ("semval for member %d is %d\n", member, semval);
d4a28ab0
CW
296}
297
fe3a7d70
CW
298void
299usage (void)
d4a28ab0 300{
fe3a7d70
CW
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);
d4a28ab0 308}
This page took 0.066818 seconds and 5 git commands to generate.