Deleted Added
full compact
t-sem.c (302408) t-sem.c (147078)
1/*
1/*
2 * Copyright (c) 2000-2001, 2005-2008 Proofpoint, Inc. and its suppliers.
2 * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers.
3 * All rights reserved.
4 *
5 * By using this file, you agree to the terms and conditions set
6 * forth in the LICENSE file which can be found at the top level of
7 * the sendmail distribution.
8 */
9
10#include <sm/gen.h>
3 * All rights reserved.
4 *
5 * By using this file, you agree to the terms and conditions set
6 * forth in the LICENSE file which can be found at the top level of
7 * the sendmail distribution.
8 */
9
10#include <sm/gen.h>
11SM_RCSID("@(#)$Id: t-sem.c,v 1.18 2013-11-22 20:51:43 ca Exp $")
11SM_RCSID("@(#)$Id: t-sem.c,v 1.14 2005/03/25 21:27:41 ca Exp $")
12
13#include <stdio.h>
14
15#if SM_CONF_SEM
16# include <stdlib.h>
17# include <unistd.h>
18# include <sysexits.h>
19# include <sm/heap.h>
20# include <sm/string.h>
21# include <sm/signal.h>
22# include <sm/test.h>
23# include <sm/sem.h>
24
12
13#include <stdio.h>
14
15#if SM_CONF_SEM
16# include <stdlib.h>
17# include <unistd.h>
18# include <sysexits.h>
19# include <sm/heap.h>
20# include <sm/string.h>
21# include <sm/signal.h>
22# include <sm/test.h>
23# include <sm/sem.h>
24
25# define T_SM_SEM_KEY (4321L)
26
27static void
28delay(t, s)
29 int t;
30 char *s;
31{
32 if (t > 0)
33 {
34#if DEBUG
35 fprintf(stderr, "sleep(%d) before %s\n", t, s);
36#endif /* DEBUG */
37 sleep(t);
38 }
39#if DEBUG
40 fprintf(stderr, "%s\n", s);
41#endif /* DEBUG */
42}
43
44
45/*
46** SEMINTER -- interactive testing of semaphores.
47**
48** Parameters:
49** owner -- create semaphores.
50**
51** Returns:
52** 0 on success
53** < 0 on failure.
54*/
55
56static int
57seminter(owner)
58 bool owner;
59{
60 int semid;
61 int t;
62
25static void
26delay(t, s)
27 int t;
28 char *s;
29{
30 if (t > 0)
31 {
32#if DEBUG
33 fprintf(stderr, "sleep(%d) before %s\n", t, s);
34#endif /* DEBUG */
35 sleep(t);
36 }
37#if DEBUG
38 fprintf(stderr, "%s\n", s);
39#endif /* DEBUG */
40}
41
42
43/*
44** SEMINTER -- interactive testing of semaphores.
45**
46** Parameters:
47** owner -- create semaphores.
48**
49** Returns:
50** 0 on success
51** < 0 on failure.
52*/
53
54static int
55seminter(owner)
56 bool owner;
57{
58 int semid;
59 int t;
60
63 semid = sm_sem_start(T_SM_SEM_KEY, SM_NSEM, 0, owner);
61 semid = sm_sem_start(SM_SEM_KEY, SM_NSEM, 0, owner);
64 if (semid < 0)
65 {
66 perror("sm_sem_start failed");
67 return 1;
68 }
69
70 while ((t = getchar()) != EOF)
71 {
72 switch (t)
73 {
74 case 'a':
75 delay(0, "try to acq");
76 if (sm_sem_acq(semid, 0, 2) < 0)
77 {
78 perror("sm_sem_acq failed");
79 return 1;
80 }
81 delay(0, "acquired");
82 break;
83
84 case 'r':
85 delay(0, "try to rel");
86 if (sm_sem_rel(semid, 0, 2) < 0)
87 {
88 perror("sm_sem_rel failed");
89 return 1;
90 }
91 delay(0, "released");
92 break;
93
94 case 'v':
95 if ((t = sm_sem_get(semid, 0)) < 0)
96 {
97 perror("get_sem failed");
98 return 1;
99 }
100 printf("semval: %d\n", t);
101 break;
102
103 }
104 }
105 if (owner)
106 return sm_sem_stop(semid);
107 return 0;
108}
109
110/*
111** SEM_CLEANUP -- cleanup if something breaks
112**
113** Parameters:
114** sig -- signal.
115**
116** Returns:
117** none.
118*/
119
120static int semid_c = -1;
121void
122sem_cleanup(sig)
123 int sig;
124{
125 if (semid_c >= 0)
126 (void) sm_sem_stop(semid_c);
127 exit(EX_UNAVAILABLE);
128}
129
62 if (semid < 0)
63 {
64 perror("sm_sem_start failed");
65 return 1;
66 }
67
68 while ((t = getchar()) != EOF)
69 {
70 switch (t)
71 {
72 case 'a':
73 delay(0, "try to acq");
74 if (sm_sem_acq(semid, 0, 2) < 0)
75 {
76 perror("sm_sem_acq failed");
77 return 1;
78 }
79 delay(0, "acquired");
80 break;
81
82 case 'r':
83 delay(0, "try to rel");
84 if (sm_sem_rel(semid, 0, 2) < 0)
85 {
86 perror("sm_sem_rel failed");
87 return 1;
88 }
89 delay(0, "released");
90 break;
91
92 case 'v':
93 if ((t = sm_sem_get(semid, 0)) < 0)
94 {
95 perror("get_sem failed");
96 return 1;
97 }
98 printf("semval: %d\n", t);
99 break;
100
101 }
102 }
103 if (owner)
104 return sm_sem_stop(semid);
105 return 0;
106}
107
108/*
109** SEM_CLEANUP -- cleanup if something breaks
110**
111** Parameters:
112** sig -- signal.
113**
114** Returns:
115** none.
116*/
117
118static int semid_c = -1;
119void
120sem_cleanup(sig)
121 int sig;
122{
123 if (semid_c >= 0)
124 (void) sm_sem_stop(semid_c);
125 exit(EX_UNAVAILABLE);
126}
127
130static int
131drop_priv(uid, gid)
132 uid_t uid;
133 gid_t gid;
134{
135 int r;
136
137 r = setgid(gid);
138 if (r != 0)
139 return r;
140 r = setuid(uid);
141 return r;
142}
143
144/*
145** SEMTEST -- test of semaphores
146**
147** Parameters:
148** owner -- create semaphores.
149**
150** Returns:
151** 0 on success
152** < 0 on failure.
153*/
154
155# define MAX_CNT 10
156
157static int
128/*
129** SEMTEST -- test of semaphores
130**
131** Parameters:
132** owner -- create semaphores.
133**
134** Returns:
135** 0 on success
136** < 0 on failure.
137*/
138
139# define MAX_CNT 10
140
141static int
158semtest(owner, uid, gid)
142semtest(owner)
159 int owner;
143 int owner;
160 uid_t uid;
161 gid_t gid;
162{
163 int semid, r;
164 int cnt = 0;
165
144{
145 int semid, r;
146 int cnt = 0;
147
166 if (!owner && uid != 0)
167 {
168 r = drop_priv(uid, gid);
169 if (r < 0)
170 {
171 perror("drop_priv child failed");
172 return -1;
173 }
174 }
175 semid = sm_sem_start(T_SM_SEM_KEY, 1, 0, owner);
148 semid = sm_sem_start(SM_SEM_KEY, 1, 0, owner);
176 if (semid < 0)
177 {
178 perror("sm_sem_start failed");
179 return -1;
180 }
181
182 if (owner)
183 {
149 if (semid < 0)
150 {
151 perror("sm_sem_start failed");
152 return -1;
153 }
154
155 if (owner)
156 {
184 if (uid != 0)
185 {
186 r = sm_semsetowner(semid, uid, gid, 0660);
187 if (r < 0)
188 {
189 perror("sm_semsetowner failed");
190 return -1;
191 }
192 r = drop_priv(uid, gid);
193 if (r < 0)
194 {
195 perror("drop_priv owner failed");
196 return -1;
197 }
198 }
199
200 /* just in case someone kills the program... */
201 semid_c = semid;
202 (void) sm_signal(SIGHUP, sem_cleanup);
203 (void) sm_signal(SIGINT, sem_cleanup);
204 (void) sm_signal(SIGTERM, sem_cleanup);
205
206 delay(1, "parent: acquire 1");
207 cnt = 0;
208 do
209 {
210 r = sm_sem_acq(semid, 0, 0);
211 if (r < 0)
212 {
213 sleep(1);
214 ++cnt;
215 }
216 } while (r < 0 && cnt <= MAX_CNT);
217 SM_TEST(r >= 0);
218 if (r < 0)
219 return r;
220
221 delay(3, "parent: release 1");
222 cnt = 0;
223 do
224 {
225 r = sm_sem_rel(semid, 0, 0);
226 if (r < 0)
227 {
228 sleep(1);
229 ++cnt;
230 }
231 } while (r < 0 && cnt <= MAX_CNT);
232 SM_TEST(r >= 0);
233 if (r < 0)
234 return r;
235
236 delay(1, "parent: getval");
237 cnt = 0;
238 do
239 {
240 r = sm_sem_get(semid, 0);
241 if (r <= 0)
242 {
243 sleep(1);
244 ++cnt;
245 }
246 } while (r <= 0 && cnt <= MAX_CNT);
247 SM_TEST(r > 0);
248 if (r <= 0)
249 return r;
250
251 delay(1, "parent: acquire 2");
252 cnt = 0;
253 do
254 {
255 r = sm_sem_acq(semid, 0, 0);
256 if (r < 0)
257 {
258 sleep(1);
259 ++cnt;
260 }
261 } while (r < 0 && cnt <= MAX_CNT);
262 SM_TEST(r >= 0);
263 if (r < 0)
264 return r;
265
266 cnt = 0;
267 do
268 {
269 r = sm_sem_rel(semid, 0, 0);
270 if (r < 0)
271 {
272 sleep(1);
273 ++cnt;
274 }
275 } while (r < 0 && cnt <= MAX_CNT);
276 SM_TEST(r >= 0);
277 if (r < 0)
278 return r;
279 }
280 else
281 {
282 delay(1, "child: acquire 1");
283 cnt = 0;
284 do
285 {
286 r = sm_sem_acq(semid, 0, 0);
287 if (r < 0)
288 {
289 sleep(1);
290 ++cnt;
291 }
292 } while (r < 0 && cnt <= MAX_CNT);
293 SM_TEST(r >= 0);
294 if (r < 0)
295 return r;
296
297 delay(1, "child: release 1");
298 cnt = 0;
299 do
300 {
301 r = sm_sem_rel(semid, 0, 0);
302 if (r < 0)
303 {
304 sleep(1);
305 ++cnt;
306 }
307 } while (r < 0 && cnt <= MAX_CNT);
308 SM_TEST(r >= 0);
309 if (r < 0)
310 return r;
311
312 }
313 if (owner)
314 return sm_sem_stop(semid);
315 return 0;
316}
317
318int
319main(argc, argv)
320 int argc;
321 char *argv[];
322{
323 bool interactive = false;
324 bool owner = false;
157 /* just in case someone kills the program... */
158 semid_c = semid;
159 (void) sm_signal(SIGHUP, sem_cleanup);
160 (void) sm_signal(SIGINT, sem_cleanup);
161 (void) sm_signal(SIGTERM, sem_cleanup);
162
163 delay(1, "parent: acquire 1");
164 cnt = 0;
165 do
166 {
167 r = sm_sem_acq(semid, 0, 0);
168 if (r < 0)
169 {
170 sleep(1);
171 ++cnt;
172 }
173 } while (r < 0 && cnt <= MAX_CNT);
174 SM_TEST(r >= 0);
175 if (r < 0)
176 return r;
177
178 delay(3, "parent: release 1");
179 cnt = 0;
180 do
181 {
182 r = sm_sem_rel(semid, 0, 0);
183 if (r < 0)
184 {
185 sleep(1);
186 ++cnt;
187 }
188 } while (r < 0 && cnt <= MAX_CNT);
189 SM_TEST(r >= 0);
190 if (r < 0)
191 return r;
192
193 delay(1, "parent: getval");
194 cnt = 0;
195 do
196 {
197 r = sm_sem_get(semid, 0);
198 if (r <= 0)
199 {
200 sleep(1);
201 ++cnt;
202 }
203 } while (r <= 0 && cnt <= MAX_CNT);
204 SM_TEST(r > 0);
205 if (r <= 0)
206 return r;
207
208 delay(1, "parent: acquire 2");
209 cnt = 0;
210 do
211 {
212 r = sm_sem_acq(semid, 0, 0);
213 if (r < 0)
214 {
215 sleep(1);
216 ++cnt;
217 }
218 } while (r < 0 && cnt <= MAX_CNT);
219 SM_TEST(r >= 0);
220 if (r < 0)
221 return r;
222
223 cnt = 0;
224 do
225 {
226 r = sm_sem_rel(semid, 0, 0);
227 if (r < 0)
228 {
229 sleep(1);
230 ++cnt;
231 }
232 } while (r < 0 && cnt <= MAX_CNT);
233 SM_TEST(r >= 0);
234 if (r < 0)
235 return r;
236 }
237 else
238 {
239 delay(1, "child: acquire 1");
240 cnt = 0;
241 do
242 {
243 r = sm_sem_acq(semid, 0, 0);
244 if (r < 0)
245 {
246 sleep(1);
247 ++cnt;
248 }
249 } while (r < 0 && cnt <= MAX_CNT);
250 SM_TEST(r >= 0);
251 if (r < 0)
252 return r;
253
254 delay(1, "child: release 1");
255 cnt = 0;
256 do
257 {
258 r = sm_sem_rel(semid, 0, 0);
259 if (r < 0)
260 {
261 sleep(1);
262 ++cnt;
263 }
264 } while (r < 0 && cnt <= MAX_CNT);
265 SM_TEST(r >= 0);
266 if (r < 0)
267 return r;
268
269 }
270 if (owner)
271 return sm_sem_stop(semid);
272 return 0;
273}
274
275int
276main(argc, argv)
277 int argc;
278 char *argv[];
279{
280 bool interactive = false;
281 bool owner = false;
325 int ch, r;
326 uid_t uid;
327 gid_t gid;
282 int ch;
283 int r = 0;
328
284
329 uid = 0;
330 gid = 0;
331 r = 0;
332
333# define OPTIONS "iog:u:"
285# define OPTIONS "io"
334 while ((ch = getopt(argc, argv, OPTIONS)) != -1)
335 {
336 switch ((char) ch)
337 {
286 while ((ch = getopt(argc, argv, OPTIONS)) != -1)
287 {
288 switch ((char) ch)
289 {
338 case 'g':
339 gid = (gid_t)strtoul(optarg, 0, 0);
340 break;
341
342 case 'i':
343 interactive = true;
344 break;
345
290 case 'i':
291 interactive = true;
292 break;
293
346 case 'u':
347 uid = (uid_t)strtoul(optarg, 0, 0);
348 break;
349
350 case 'o':
351 owner = true;
352 break;
353
354 default:
355 break;
356 }
357 }
358
359 if (interactive)
360 r = seminter(owner);
361 else
362 {
363 pid_t pid;
364
365 printf("This test takes about 8 seconds.\n");
294 case 'o':
295 owner = true;
296 break;
297
298 default:
299 break;
300 }
301 }
302
303 if (interactive)
304 r = seminter(owner);
305 else
306 {
307 pid_t pid;
308
309 printf("This test takes about 8 seconds.\n");
366 printf("If it takes longer than 30 seconds, please interrupt it\n");
310 printf("If it takes longer than 30 second, please interrupt it\n");
367 printf("and compile again without semaphore support, i.e.,");
368 printf("-DSM_CONF_SEM=0\n");
369 if ((pid = fork()) < 0)
370 {
371 perror("fork failed\n");
372 return -1;
373 }
374
375 sm_test_begin(argc, argv, "test semaphores");
376 if (pid == 0)
377 {
378 /* give the parent the chance to setup data */
379 sleep(1);
311 printf("and compile again without semaphore support, i.e.,");
312 printf("-DSM_CONF_SEM=0\n");
313 if ((pid = fork()) < 0)
314 {
315 perror("fork failed\n");
316 return -1;
317 }
318
319 sm_test_begin(argc, argv, "test semaphores");
320 if (pid == 0)
321 {
322 /* give the parent the chance to setup data */
323 sleep(1);
380 r = semtest(false, uid, gid);
324 r = semtest(false);
381 }
382 else
383 {
325 }
326 else
327 {
384 r = semtest(true, uid, gid);
328 r = semtest(true);
385 }
386 SM_TEST(r == 0);
387 return sm_test_end();
388 }
389 return r;
390}
391#else /* SM_CONF_SEM */
392int
393main(argc, argv)
394 int argc;
395 char *argv[];
396{
397 printf("No support for semaphores configured on this machine\n");
398 return 0;
399}
400#endif /* SM_CONF_SEM */
329 }
330 SM_TEST(r == 0);
331 return sm_test_end();
332 }
333 return r;
334}
335#else /* SM_CONF_SEM */
336int
337main(argc, argv)
338 int argc;
339 char *argv[];
340{
341 printf("No support for semaphores configured on this machine\n");
342 return 0;
343}
344#endif /* SM_CONF_SEM */