2 * Copyright (c) 2000-2001, 2005-2008 Sendmail, Inc. and its suppliers.
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.
11 SM_RCSID("@(#)$Id: t-sem.c,v 1.17 2008/05/30 16:26:38 ca Exp $")
18 # include <sysexits.h>
20 # include <sm/string.h>
21 # include <sm/signal.h>
25 # define T_SM_SEM_KEY (4321L)
35 fprintf(stderr
, "sleep(%d) before %s\n", t
, s
);
40 fprintf(stderr
, "%s\n", s
);
46 ** SEMINTER -- interactive testing of semaphores.
49 ** owner -- create semaphores.
63 semid
= sm_sem_start(T_SM_SEM_KEY
, SM_NSEM
, 0, owner
);
66 perror("sm_sem_start failed");
70 while ((t
= getchar()) != EOF
)
75 delay(0, "try to acq");
76 if (sm_sem_acq(semid
, 0, 2) < 0)
78 perror("sm_sem_acq failed");
85 delay(0, "try to rel");
86 if (sm_sem_rel(semid
, 0, 2) < 0)
88 perror("sm_sem_rel failed");
95 if ((t
= sm_sem_get(semid
, 0)) < 0)
97 perror("get_sem failed");
100 printf("semval: %d\n", t
);
106 return sm_sem_stop(semid
);
111 ** SEM_CLEANUP -- cleanup if something breaks
120 static int semid_c
= -1;
126 (void) sm_sem_stop(semid_c
);
127 exit(EX_UNAVAILABLE
);
145 ** SEMTEST -- test of semaphores
148 ** owner -- create semaphores.
158 semtest(owner
, uid
, gid
)
166 if (!owner
&& uid
!= 0)
168 r
= drop_priv(uid
, gid
);
171 perror("drop_priv child failed");
175 semid
= sm_sem_start(T_SM_SEM_KEY
, 1, 0, owner
);
178 perror("sm_sem_start failed");
186 r
= sm_semsetowner(semid
, uid
, gid
, 0660);
189 perror("sm_semsetowner failed");
192 r
= drop_priv(uid
, gid
);
195 perror("drop_priv owner failed");
200 /* just in case someone kills the program... */
202 (void) sm_signal(SIGHUP
, sem_cleanup
);
203 (void) sm_signal(SIGINT
, sem_cleanup
);
204 (void) sm_signal(SIGTERM
, sem_cleanup
);
206 delay(1, "parent: acquire 1");
210 r
= sm_sem_acq(semid
, 0, 0);
216 } while (r
< 0 && cnt
<= MAX_CNT
);
221 delay(3, "parent: release 1");
225 r
= sm_sem_rel(semid
, 0, 0);
231 } while (r
< 0 && cnt
<= MAX_CNT
);
236 delay(1, "parent: getval");
240 r
= sm_sem_get(semid
, 0);
246 } while (r
<= 0 && cnt
<= MAX_CNT
);
251 delay(1, "parent: acquire 2");
255 r
= sm_sem_acq(semid
, 0, 0);
261 } while (r
< 0 && cnt
<= MAX_CNT
);
269 r
= sm_sem_rel(semid
, 0, 0);
275 } while (r
< 0 && cnt
<= MAX_CNT
);
282 delay(1, "child: acquire 1");
286 r
= sm_sem_acq(semid
, 0, 0);
292 } while (r
< 0 && cnt
<= MAX_CNT
);
297 delay(1, "child: release 1");
301 r
= sm_sem_rel(semid
, 0, 0);
307 } while (r
< 0 && cnt
<= MAX_CNT
);
314 return sm_sem_stop(semid
);
323 bool interactive
= false;
333 # define OPTIONS "iog:u:"
334 while ((ch
= getopt(argc
, argv
, OPTIONS
)) != -1)
339 gid
= (gid_t
)strtoul(optarg
, 0, 0);
347 uid
= (uid_t
)strtoul(optarg
, 0, 0);
365 printf("This test takes about 8 seconds.\n");
366 printf("If it takes longer than 30 seconds, 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)
371 perror("fork failed\n");
375 sm_test_begin(argc
, argv
, "test semaphores");
378 /* give the parent the chance to setup data */
380 r
= semtest(false, uid
, gid
);
384 r
= semtest(true, uid
, gid
);
387 return sm_test_end();
391 #else /* SM_CONF_SEM */
397 printf("No support for semaphores configured on this machine\n");
400 #endif /* SM_CONF_SEM */