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