1 
2 #include <sys/types.h>
3 #include <sys/wait.h>
4 #include <sys/mman.h>
5 #include <semaphore.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <err.h>
9 #include <errno.h>
10 #include <fcntl.h>
11 #include <unistd.h>
12 
13 #define SEM_NAME "/semtst"
14 
15 int test_unnamed(void);
16 int test_named(void);
17 int test_named2(void);
18 
19 int
20 test_unnamed(void)
21 {
22 	sem_t *s;
23 	pid_t pid;
24 	int status;
25 
26 	printf("testing unnamed process-shared semaphore\n");
27 	s = (sem_t *)mmap(NULL, sizeof(sem_t), PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED,
28 		-1, 0);
29 	if (s == MAP_FAILED)
30 		err(1, "mmap failed");
31 	if (sem_init(s, 1, 0))
32 		err(2, "sem_init failed");
33 	if ((pid = fork()) == 0) {
34 		printf("child: sem_wait()\n");
35 		if (sem_wait(s))
36 			err(3, "sem_wait failed");
37 		printf("child: sem_wait() returned\n");
38 		exit(0);
39 	} else {
40 		sleep(1);
41 		printf("parent: sem_post()\n");
42 		if (sem_post(s))
43 			err(4, "sem_post failed");
44 		waitpid(pid, &status, 0);
45 		if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
46 			printf("OK.\n");
47 		else
48 			printf("Failure.");
49 	}
50 	return (0);
51 }
52 
53 int
54 test_named(void)
55 {
56 	sem_t *s, *s2;
57 	pid_t pid;
58 	int status;
59 
60 	printf("testing named process-shared semaphore\n");
61 	sem_unlink(SEM_NAME);
62 	s = sem_open(SEM_NAME, O_CREAT, 0777, 0);
63 	if (s == SEM_FAILED)
64 		err(1, "sem_open failed");
65 	s2 = sem_open(SEM_NAME, O_CREAT, 0777, 0);
66 	if (s2 == SEM_FAILED)
67 		err(2, "second sem_open call failed");
68 	if (s != s2)
69 		errx(3,
70 "two sem_open calls for same semaphore do not return same address");
71 	if (sem_close(s2))
72 		err(4, "sem_close failed");
73 	if ((pid = fork()) == 0) {
74 		printf("child: sem_wait()\n");
75 		if (sem_wait(s))
76 			err(5, "sem_wait failed");
77 		printf("child: sem_wait() returned\n");
78 		exit(0);
79 	} else {
80 		sleep(1);
81 		printf("parent: sem_post()\n");
82 		if (sem_post(s))
83 			err(6, "sem_post failed");
84 		waitpid(pid, &status, 0);
85 		if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
86 			printf("OK.\n");
87 		else
88 			printf("Failure.");
89 	}
90 
91 	if (sem_close(s))
92 		err(7, "sem_close failed");
93 
94 	return (0);
95 }
96 
97 int
98 test_named2(void)
99 {
100 	sem_t *s, *s2, *s3;
101 
102 	printf("testing named process-shared semaphore, O_EXCL cases\n");
103 	sem_unlink(SEM_NAME);
104 	s = sem_open(SEM_NAME, O_CREAT | O_EXCL, 0777, 0);
105 	if (s == SEM_FAILED)
106 		err(1, "sem_open failed");
107 	s2 = sem_open(SEM_NAME, O_CREAT | O_EXCL, 0777, 0);
108 	if (s2 != SEM_FAILED)
109 		errx(2, "second sem_open call wrongly succeeded");
110 	if (errno != EEXIST)
111 		err(3, "second sem_open call failed with wrong errno");
112 
113 	s3 = sem_open(SEM_NAME, 0);
114 	if (s3 == SEM_FAILED)
115 		err(4, "third sem_open call failed");
116 	if (s != s3)
117 		errx(5,
118 "two sem_open calls for same semaphore do not return same address");
119 	if (sem_close(s3))
120 		err(6, "sem_close failed");
121 
122 	if (sem_close(s))
123 		err(7, "sem_close failed");
124 
125 	printf("OK.\n");
126 	return (0);
127 }
128 
129 int
130 main(void)
131 {
132 	test_unnamed();
133 	test_named();
134 	test_named2();
135 	return (0);
136 }
137