1 /* $FreeBSD$ */
2 
3 #include <sys/types.h>
4 #include <sys/wait.h>
5 #include <sys/mman.h>
6 #include <semaphore.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <err.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 
18 int
19 test_unnamed(void)
20 {
21 	sem_t *s;
22 	pid_t pid;
23 	int status;
24 
25 	printf("testing unnamed process-shared semaphore\n");
26 	s = (sem_t *)mmap(NULL, sizeof(sem_t), PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED,
27 		-1, 0);
28 	if (s == MAP_FAILED)
29 		err(1, "mmap failed");
30 	if (sem_init(s, 1, 0))
31 		err(2, "sem_init failed");
32 	if ((pid = fork()) == 0) {
33 		printf("child: sem_wait()\n");
34 		if (sem_wait(s))
35 			err(3, "sem_wait failed");
36 		printf("child: sem_wait() returned\n");
37 		exit(0);
38 	} else {
39 		sleep(1);
40 		printf("parent: sem_post()\n");
41 		if (sem_post(s))
42 			err(4, "sem_post failed");
43 		waitpid(pid, &status, 0);
44 		if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
45 			printf("OK.\n");
46 		else
47 			printf("Failure.");
48 	}
49 	return (0);
50 }
51 
52 int
53 test_named(void)
54 {
55 	sem_t *s, *s2;
56 	pid_t pid;
57 	int status;
58 
59 	printf("testing named process-shared semaphore\n");
60 	sem_unlink(SEM_NAME);
61 	s = sem_open(SEM_NAME, O_CREAT, 0777, 0);
62 	if (s == SEM_FAILED)
63 		err(1, "sem_open failed");
64 	s2 = sem_open(SEM_NAME, O_CREAT, 0777, 0);
65 	if (s2 == SEM_FAILED)
66 		err(2, "second sem_open call failed");
67 	if (s != s2)
68 		errx(3,
69 "two sem_open calls for same semaphore do not return same address");
70 	if (sem_close(s2))
71 		err(4, "sem_close failed");
72 	if ((pid = fork()) == 0) {
73 		printf("child: sem_wait()\n");
74 		if (sem_wait(s))
75 			err(5, "sem_wait failed");
76 		printf("child: sem_wait() returned\n");
77 		exit(0);
78 	} else {
79 		sleep(1);
80 		printf("parent: sem_post()\n");
81 		if (sem_post(s))
82 			err(6, "sem_post failed");
83 		waitpid(pid, &status, 0);
84 		if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
85 			printf("OK.\n");
86 		else
87 			printf("Failure.");
88 	}
89 
90 	if (sem_close(s))
91 		err(7, "sem_close failed");
92 
93 	return (0);
94 }
95 
96 int
97 main(void)
98 {
99 	test_unnamed();
100 	test_named();
101 	return (0);
102 }
103