mountctl(8): Improve Synopsis & sync usage(), also improve markup
[dragonfly.git] / contrib / sendmail-8.14 / libsm / t-sem.c
blob24d056365fab268b0bfd84ae8dcc8443a150c0ac
1 /*
2 * Copyright (c) 2000-2001, 2005-2007 Sendmail, Inc. and its suppliers.
3 * All rights reserved.
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 */
10 #include <sm/gen.h>
11 SM_RCSID("@(#)$Id: t-sem.c,v 1.16 2007/03/21 23:22:10 ca Exp $")
13 #include <stdio.h>
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>
25 # define T_SM_SEM_KEY (4321L)
27 static void
28 delay(t, s)
29 int t;
30 char *s;
32 if (t > 0)
34 #if DEBUG
35 fprintf(stderr, "sleep(%d) before %s\n", t, s);
36 #endif /* DEBUG */
37 sleep(t);
39 #if DEBUG
40 fprintf(stderr, "%s\n", s);
41 #endif /* DEBUG */
46 ** SEMINTER -- interactive testing of semaphores.
48 ** Parameters:
49 ** owner -- create semaphores.
51 ** Returns:
52 ** 0 on success
53 ** < 0 on failure.
56 static int
57 seminter(owner)
58 bool owner;
60 int semid;
61 int t;
63 semid = sm_sem_start(T_SM_SEM_KEY, SM_NSEM, 0, owner);
64 if (semid < 0)
66 perror("sm_sem_start failed");
67 return 1;
70 while ((t = getchar()) != EOF)
72 switch (t)
74 case 'a':
75 delay(0, "try to acq");
76 if (sm_sem_acq(semid, 0, 2) < 0)
78 perror("sm_sem_acq failed");
79 return 1;
81 delay(0, "acquired");
82 break;
84 case 'r':
85 delay(0, "try to rel");
86 if (sm_sem_rel(semid, 0, 2) < 0)
88 perror("sm_sem_rel failed");
89 return 1;
91 delay(0, "released");
92 break;
94 case 'v':
95 if ((t = sm_sem_get(semid, 0)) < 0)
97 perror("get_sem failed");
98 return 1;
100 printf("semval: %d\n", t);
101 break;
105 if (owner)
106 return sm_sem_stop(semid);
107 return 0;
111 ** SEM_CLEANUP -- cleanup if something breaks
113 ** Parameters:
114 ** sig -- signal.
116 ** Returns:
117 ** none.
120 static int semid_c = -1;
121 void
122 sem_cleanup(sig)
123 int sig;
125 if (semid_c >= 0)
126 (void) sm_sem_stop(semid_c);
127 exit(EX_UNAVAILABLE);
131 ** SEMTEST -- test of semaphores
133 ** Parameters:
134 ** owner -- create semaphores.
136 ** Returns:
137 ** 0 on success
138 ** < 0 on failure.
141 # define MAX_CNT 10
143 static int
144 semtest(owner)
145 int owner;
147 int semid, r;
148 int cnt = 0;
150 semid = sm_sem_start(T_SM_SEM_KEY, 1, 0, owner);
151 if (semid < 0)
153 perror("sm_sem_start failed");
154 return -1;
157 if (owner)
159 /* just in case someone kills the program... */
160 semid_c = semid;
161 (void) sm_signal(SIGHUP, sem_cleanup);
162 (void) sm_signal(SIGINT, sem_cleanup);
163 (void) sm_signal(SIGTERM, sem_cleanup);
165 delay(1, "parent: acquire 1");
166 cnt = 0;
169 r = sm_sem_acq(semid, 0, 0);
170 if (r < 0)
172 sleep(1);
173 ++cnt;
175 } while (r < 0 && cnt <= MAX_CNT);
176 SM_TEST(r >= 0);
177 if (r < 0)
178 return r;
180 delay(3, "parent: release 1");
181 cnt = 0;
184 r = sm_sem_rel(semid, 0, 0);
185 if (r < 0)
187 sleep(1);
188 ++cnt;
190 } while (r < 0 && cnt <= MAX_CNT);
191 SM_TEST(r >= 0);
192 if (r < 0)
193 return r;
195 delay(1, "parent: getval");
196 cnt = 0;
199 r = sm_sem_get(semid, 0);
200 if (r <= 0)
202 sleep(1);
203 ++cnt;
205 } while (r <= 0 && cnt <= MAX_CNT);
206 SM_TEST(r > 0);
207 if (r <= 0)
208 return r;
210 delay(1, "parent: acquire 2");
211 cnt = 0;
214 r = sm_sem_acq(semid, 0, 0);
215 if (r < 0)
217 sleep(1);
218 ++cnt;
220 } while (r < 0 && cnt <= MAX_CNT);
221 SM_TEST(r >= 0);
222 if (r < 0)
223 return r;
225 cnt = 0;
228 r = sm_sem_rel(semid, 0, 0);
229 if (r < 0)
231 sleep(1);
232 ++cnt;
234 } while (r < 0 && cnt <= MAX_CNT);
235 SM_TEST(r >= 0);
236 if (r < 0)
237 return r;
239 else
241 delay(1, "child: acquire 1");
242 cnt = 0;
245 r = sm_sem_acq(semid, 0, 0);
246 if (r < 0)
248 sleep(1);
249 ++cnt;
251 } while (r < 0 && cnt <= MAX_CNT);
252 SM_TEST(r >= 0);
253 if (r < 0)
254 return r;
256 delay(1, "child: release 1");
257 cnt = 0;
260 r = sm_sem_rel(semid, 0, 0);
261 if (r < 0)
263 sleep(1);
264 ++cnt;
266 } while (r < 0 && cnt <= MAX_CNT);
267 SM_TEST(r >= 0);
268 if (r < 0)
269 return r;
272 if (owner)
273 return sm_sem_stop(semid);
274 return 0;
278 main(argc, argv)
279 int argc;
280 char *argv[];
282 bool interactive = false;
283 bool owner = false;
284 int ch;
285 int r = 0;
287 # define OPTIONS "io"
288 while ((ch = getopt(argc, argv, OPTIONS)) != -1)
290 switch ((char) ch)
292 case 'i':
293 interactive = true;
294 break;
296 case 'o':
297 owner = true;
298 break;
300 default:
301 break;
305 if (interactive)
306 r = seminter(owner);
307 else
309 pid_t pid;
311 printf("This test takes about 8 seconds.\n");
312 printf("If it takes longer than 30 seconds, please interrupt it\n");
313 printf("and compile again without semaphore support, i.e.,");
314 printf("-DSM_CONF_SEM=0\n");
315 if ((pid = fork()) < 0)
317 perror("fork failed\n");
318 return -1;
321 sm_test_begin(argc, argv, "test semaphores");
322 if (pid == 0)
324 /* give the parent the chance to setup data */
325 sleep(1);
326 r = semtest(false);
328 else
330 r = semtest(true);
332 SM_TEST(r == 0);
333 return sm_test_end();
335 return r;
337 #else /* SM_CONF_SEM */
339 main(argc, argv)
340 int argc;
341 char *argv[];
343 printf("No support for semaphores configured on this machine\n");
344 return 0;
346 #endif /* SM_CONF_SEM */