13df967d5SDavid Xu
23df967d5SDavid Xu #include <sys/types.h>
33df967d5SDavid Xu #include <sys/wait.h>
43df967d5SDavid Xu #include <sys/mman.h>
53df967d5SDavid Xu #include <semaphore.h>
63df967d5SDavid Xu #include <stdio.h>
73df967d5SDavid Xu #include <stdlib.h>
83df967d5SDavid Xu #include <err.h>
9*afa04e41SJilles Tjoelker #include <errno.h>
103df967d5SDavid Xu #include <fcntl.h>
113df967d5SDavid Xu #include <unistd.h>
123df967d5SDavid Xu
133df967d5SDavid Xu #define SEM_NAME "/semtst"
143df967d5SDavid Xu
153df967d5SDavid Xu int test_unnamed(void);
163df967d5SDavid Xu int test_named(void);
17*afa04e41SJilles Tjoelker int test_named2(void);
183df967d5SDavid Xu
193df967d5SDavid Xu int
test_unnamed(void)203df967d5SDavid Xu test_unnamed(void)
213df967d5SDavid Xu {
223df967d5SDavid Xu sem_t *s;
233df967d5SDavid Xu pid_t pid;
243df967d5SDavid Xu int status;
253df967d5SDavid Xu
263df967d5SDavid Xu printf("testing unnamed process-shared semaphore\n");
273df967d5SDavid Xu s = (sem_t *)mmap(NULL, sizeof(sem_t), PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED,
283df967d5SDavid Xu -1, 0);
293df967d5SDavid Xu if (s == MAP_FAILED)
303df967d5SDavid Xu err(1, "mmap failed");
313df967d5SDavid Xu if (sem_init(s, 1, 0))
323df967d5SDavid Xu err(2, "sem_init failed");
333df967d5SDavid Xu if ((pid = fork()) == 0) {
343df967d5SDavid Xu printf("child: sem_wait()\n");
353df967d5SDavid Xu if (sem_wait(s))
363df967d5SDavid Xu err(3, "sem_wait failed");
373df967d5SDavid Xu printf("child: sem_wait() returned\n");
383df967d5SDavid Xu exit(0);
393df967d5SDavid Xu } else {
403df967d5SDavid Xu sleep(1);
413df967d5SDavid Xu printf("parent: sem_post()\n");
423df967d5SDavid Xu if (sem_post(s))
433df967d5SDavid Xu err(4, "sem_post failed");
443df967d5SDavid Xu waitpid(pid, &status, 0);
453df967d5SDavid Xu if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
463df967d5SDavid Xu printf("OK.\n");
473df967d5SDavid Xu else
483df967d5SDavid Xu printf("Failure.");
493df967d5SDavid Xu }
503df967d5SDavid Xu return (0);
513df967d5SDavid Xu }
523df967d5SDavid Xu
533df967d5SDavid Xu int
test_named(void)543df967d5SDavid Xu test_named(void)
553df967d5SDavid Xu {
563df967d5SDavid Xu sem_t *s, *s2;
573df967d5SDavid Xu pid_t pid;
583df967d5SDavid Xu int status;
593df967d5SDavid Xu
603df967d5SDavid Xu printf("testing named process-shared semaphore\n");
613df967d5SDavid Xu sem_unlink(SEM_NAME);
62323d80a0SDavid Xu s = sem_open(SEM_NAME, O_CREAT, 0777, 0);
633df967d5SDavid Xu if (s == SEM_FAILED)
643df967d5SDavid Xu err(1, "sem_open failed");
65323d80a0SDavid Xu s2 = sem_open(SEM_NAME, O_CREAT, 0777, 0);
663df967d5SDavid Xu if (s2 == SEM_FAILED)
673df967d5SDavid Xu err(2, "second sem_open call failed");
683df967d5SDavid Xu if (s != s2)
696e2e6716SKonstantin Belousov errx(3,
7043648bc0SKonstantin Belousov "two sem_open calls for same semaphore do not return same address");
713df967d5SDavid Xu if (sem_close(s2))
723df967d5SDavid Xu err(4, "sem_close failed");
733df967d5SDavid Xu if ((pid = fork()) == 0) {
743df967d5SDavid Xu printf("child: sem_wait()\n");
753df967d5SDavid Xu if (sem_wait(s))
763df967d5SDavid Xu err(5, "sem_wait failed");
773df967d5SDavid Xu printf("child: sem_wait() returned\n");
783df967d5SDavid Xu exit(0);
793df967d5SDavid Xu } else {
803df967d5SDavid Xu sleep(1);
813df967d5SDavid Xu printf("parent: sem_post()\n");
823df967d5SDavid Xu if (sem_post(s))
833df967d5SDavid Xu err(6, "sem_post failed");
843df967d5SDavid Xu waitpid(pid, &status, 0);
853df967d5SDavid Xu if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
863df967d5SDavid Xu printf("OK.\n");
873df967d5SDavid Xu else
883df967d5SDavid Xu printf("Failure.");
893df967d5SDavid Xu }
903df967d5SDavid Xu
913df967d5SDavid Xu if (sem_close(s))
923df967d5SDavid Xu err(7, "sem_close failed");
933df967d5SDavid Xu
943df967d5SDavid Xu return (0);
953df967d5SDavid Xu }
963df967d5SDavid Xu
973df967d5SDavid Xu int
test_named2(void)98*afa04e41SJilles Tjoelker test_named2(void)
99*afa04e41SJilles Tjoelker {
100*afa04e41SJilles Tjoelker sem_t *s, *s2, *s3;
101*afa04e41SJilles Tjoelker
102*afa04e41SJilles Tjoelker printf("testing named process-shared semaphore, O_EXCL cases\n");
103*afa04e41SJilles Tjoelker sem_unlink(SEM_NAME);
104*afa04e41SJilles Tjoelker s = sem_open(SEM_NAME, O_CREAT | O_EXCL, 0777, 0);
105*afa04e41SJilles Tjoelker if (s == SEM_FAILED)
106*afa04e41SJilles Tjoelker err(1, "sem_open failed");
107*afa04e41SJilles Tjoelker s2 = sem_open(SEM_NAME, O_CREAT | O_EXCL, 0777, 0);
108*afa04e41SJilles Tjoelker if (s2 != SEM_FAILED)
109*afa04e41SJilles Tjoelker errx(2, "second sem_open call wrongly succeeded");
110*afa04e41SJilles Tjoelker if (errno != EEXIST)
111*afa04e41SJilles Tjoelker err(3, "second sem_open call failed with wrong errno");
112*afa04e41SJilles Tjoelker
113*afa04e41SJilles Tjoelker s3 = sem_open(SEM_NAME, 0);
114*afa04e41SJilles Tjoelker if (s3 == SEM_FAILED)
115*afa04e41SJilles Tjoelker err(4, "third sem_open call failed");
116*afa04e41SJilles Tjoelker if (s != s3)
117*afa04e41SJilles Tjoelker errx(5,
118*afa04e41SJilles Tjoelker "two sem_open calls for same semaphore do not return same address");
119*afa04e41SJilles Tjoelker if (sem_close(s3))
120*afa04e41SJilles Tjoelker err(6, "sem_close failed");
121*afa04e41SJilles Tjoelker
122*afa04e41SJilles Tjoelker if (sem_close(s))
123*afa04e41SJilles Tjoelker err(7, "sem_close failed");
124*afa04e41SJilles Tjoelker
125*afa04e41SJilles Tjoelker printf("OK.\n");
126*afa04e41SJilles Tjoelker return (0);
127*afa04e41SJilles Tjoelker }
128*afa04e41SJilles Tjoelker
129*afa04e41SJilles Tjoelker int
main(void)1303df967d5SDavid Xu main(void)
1313df967d5SDavid Xu {
1323df967d5SDavid Xu test_unnamed();
1333df967d5SDavid Xu test_named();
134*afa04e41SJilles Tjoelker test_named2();
1353df967d5SDavid Xu return (0);
1363df967d5SDavid Xu }
137