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