]> cygwin.com Git - cygwin-apps/cygutils.git/blob - src/ipc/semtool.c
More changes to support cygserver and not cygipc
[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 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 */
54 void *__pad;
55 };
56
57 #define SEM_RESOURCE_MAX 1 /* Initial value of all semaphores */
58
59 void opensem(int *sid, key_t key);
60 void createsem(int *sid, key_t key, int members);
61 void locksem(int sid, int member);
62 void unlocksem(int sid, int member);
63 void removesem(int sid);
64 unsigned short get_member_count(int sid);
65 int getval(int sid, int member);
66 void dispval(int sid, int member);
67 void changemode(int sid, char *mode);
68 void usage(void);
69
70 int main(int argc, char *argv[])
71 {
72 key_t key;
73 int semset_id;
74
75 if(argc == 1)
76 usage();
77
78 /* Create unique key via call to ftok() */
79 key = ftok(".", 's');
80
81 switch(tolower(argv[1][0]))
82 {
83 case 'c': if(argc != 3)
84 usage();
85 createsem(&semset_id, key, atoi(argv[2]));
86 break;
87 case 'l': if(argc != 3)
88 usage();
89 opensem(&semset_id, key);
90 locksem(semset_id, atoi(argv[2]));
91 break;
92 case 'u': if(argc != 3)
93 usage();
94 opensem(&semset_id, key);
95 unlocksem(semset_id, atoi(argv[2]));
96 break;
97 case 'd': opensem(&semset_id, key);
98 removesem(semset_id);
99 break;
100 case 'm': opensem(&semset_id, key);
101 changemode(semset_id, argv[2]);
102 break;
103 default: usage();
104
105 }
106
107 return(0);
108 }
109
110 void opensem(int *sid, key_t key)
111 {
112 /* Open the semaphore set - do not create! */
113
114 if((*sid = semget(key, 0, 0666)) == -1)
115 {
116 printf("Semaphore set does not exist!\n");
117 exit(1);
118 }
119
120 }
121
122 void createsem(int *sid, key_t key, int members)
123 {
124 int cntr;
125 union semun semopts;
126
127 if(members > SEMMSL) {
128 printf("Sorry, max number of semaphores in a set is %d\n",
129 SEMMSL);
130 exit(1);
131 }
132
133 printf("Attempting to create new semaphore set with %d members\n",
134 members);
135
136 if((*sid = semget(key, members, IPC_CREAT|IPC_EXCL|0666))
137 == -1)
138 {
139 fprintf(stderr, "Semaphore set already exists!\n");
140 exit(1);
141 }
142
143 semopts.val = SEM_RESOURCE_MAX;
144
145 /* Initialize all members (could be done with SETALL) */
146 for(cntr=0; cntr<members; cntr++)
147 semctl(*sid, cntr, SETVAL, semopts);
148 }
149
150 void locksem(int sid, int member)
151 {
152 struct sembuf sem_lock={ 0, -1, IPC_NOWAIT};
153
154 if( member<0 || member>(get_member_count(sid)-1))
155 {
156 fprintf(stderr, "semaphore member %d out of range\n", member);
157 return;
158 }
159
160 /* Attempt to lock the semaphore set */
161 if(!getval(sid, member))
162 {
163 fprintf(stderr, "Semaphore resources exhausted (no lock)!\n");
164 exit(1);
165 }
166
167 sem_lock.sem_num = member;
168
169 if((semop(sid, &sem_lock, 1)) == -1)
170 {
171 fprintf(stderr, "Lock failed\n");
172 exit(1);
173 }
174 else
175 printf("Semaphore resources decremented by one (locked)\n");
176
177 dispval(sid, member);
178 }
179
180 void unlocksem(int sid, int member)
181 {
182 struct sembuf sem_unlock={ member, 1, IPC_NOWAIT};
183 int semval;
184
185 if( member<0 || member>(get_member_count(sid)-1))
186 {
187 fprintf(stderr, "semaphore member %d out of range\n", member);
188 return;
189 }
190
191 /* Is the semaphore set locked? */
192 semval = getval(sid, member);
193 if(semval == SEM_RESOURCE_MAX) {
194 fprintf(stderr, "Semaphore not locked!\n");
195 exit(1);
196 }
197
198 sem_unlock.sem_num = member;
199
200 /* Attempt to lock the semaphore set */
201 if((semop(sid, &sem_unlock, 1)) == -1)
202 {
203 fprintf(stderr, "Unlock failed\n");
204 exit(1);
205 }
206 else
207 printf("Semaphore resources incremented by one (unlocked)\n");
208
209 dispval(sid, member);
210 }
211
212 void removesem(int sid)
213 {
214 union semun semopts;
215 semopts.val = 0;
216
217 semctl(sid, 0, IPC_RMID, semopts);
218 printf("Semaphore removed\n");
219 }
220
221 unsigned short get_member_count(int sid)
222 {
223 union semun semopts;
224 struct semid_ds mysemds;
225
226 semopts.buf = &mysemds;
227
228 /* Return number of members in the semaphore set */
229 return(semopts.buf->sem_nsems);
230 }
231
232 int getval(int sid, int member)
233 {
234 int semval;
235 union semun semopts;
236 semopts.val = 0;
237
238 semval = semctl(sid, member, GETVAL, semopts);
239 return(semval);
240 }
241
242 void changemode(int sid, char *mode)
243 {
244 int rc;
245 union semun semopts;
246 struct semid_ds mysemds;
247
248 /* Get current values for internal data structure */
249 semopts.buf = &mysemds;
250
251 rc = semctl(sid, 0, IPC_STAT, semopts);
252
253 if (rc == -1) {
254 perror("semctl");
255 exit(1);
256 }
257
258 printf("Old permissions were %o\n", semopts.buf->sem_perm.mode);
259
260 /* Change the permissions on the semaphore */
261 sscanf(mode, "%ho", &semopts.buf->sem_perm.mode);
262
263 /* Update the internal data structure */
264 semctl(sid, 0, IPC_SET, semopts);
265
266 printf("Updated...\n");
267
268 }
269
270 void dispval(int sid, int member)
271 {
272 int semval;
273 union semun semopts;
274 semopts.val = 0;
275
276 semval = semctl(sid, member, GETVAL, semopts);
277 printf("semval for member %d is %d\n", member, semval);
278 }
279
280 void usage(void)
281 {
282 fprintf(stderr, "semtool - A utility for tinkering with semaphores\n");
283 fprintf(stderr, "\nUSAGE: semtool (c)reate <semcount>\n");
284 fprintf(stderr, " (l)ock <sem #>\n");
285 fprintf(stderr, " (u)nlock <sem #>\n");
286 fprintf(stderr, " (d)elete\n");
287 fprintf(stderr, " (m)ode <mode>\n");
288 exit(1);
289 }
This page took 0.057118 seconds and 5 git commands to generate.