1201575Sdavidxu/* $FreeBSD$ */
2201575Sdavidxu
3201575Sdavidxu#include <sys/types.h>
4201575Sdavidxu#include <sys/wait.h>
5201575Sdavidxu#include <sys/mman.h>
6201575Sdavidxu#include <semaphore.h>
7201575Sdavidxu#include <stdio.h>
8201575Sdavidxu#include <stdlib.h>
9201575Sdavidxu#include <err.h>
10294565Sjilles#include <errno.h>
11201575Sdavidxu#include <fcntl.h>
12201575Sdavidxu#include <unistd.h>
13201575Sdavidxu
14201575Sdavidxu#define SEM_NAME "/semtst"
15201575Sdavidxu
16201575Sdavidxuint test_unnamed(void);
17201575Sdavidxuint test_named(void);
18294565Sjillesint test_named2(void);
19201575Sdavidxu
20201575Sdavidxuint
21201575Sdavidxutest_unnamed(void)
22201575Sdavidxu{
23201575Sdavidxu	sem_t *s;
24201575Sdavidxu	pid_t pid;
25201575Sdavidxu	int status;
26201575Sdavidxu
27201575Sdavidxu	printf("testing unnamed process-shared semaphore\n");
28201575Sdavidxu	s = (sem_t *)mmap(NULL, sizeof(sem_t), PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED,
29201575Sdavidxu		-1, 0);
30201575Sdavidxu	if (s == MAP_FAILED)
31201575Sdavidxu		err(1, "mmap failed");
32201575Sdavidxu	if (sem_init(s, 1, 0))
33201575Sdavidxu		err(2, "sem_init failed");
34201575Sdavidxu	if ((pid = fork()) == 0) {
35201575Sdavidxu		printf("child: sem_wait()\n");
36201575Sdavidxu		if (sem_wait(s))
37201575Sdavidxu			err(3, "sem_wait failed");
38201575Sdavidxu		printf("child: sem_wait() returned\n");
39201575Sdavidxu		exit(0);
40201575Sdavidxu	} else {
41201575Sdavidxu		sleep(1);
42201575Sdavidxu		printf("parent: sem_post()\n");
43201575Sdavidxu		if (sem_post(s))
44201575Sdavidxu			err(4, "sem_post failed");
45201575Sdavidxu		waitpid(pid, &status, 0);
46201575Sdavidxu		if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
47201575Sdavidxu			printf("OK.\n");
48201575Sdavidxu		else
49201575Sdavidxu			printf("Failure.");
50201575Sdavidxu	}
51201575Sdavidxu	return (0);
52201575Sdavidxu}
53201575Sdavidxu
54201575Sdavidxuint
55201575Sdavidxutest_named(void)
56201575Sdavidxu{
57201575Sdavidxu	sem_t *s, *s2;
58201575Sdavidxu	pid_t pid;
59201575Sdavidxu	int status;
60201575Sdavidxu
61201575Sdavidxu	printf("testing named process-shared semaphore\n");
62201575Sdavidxu	sem_unlink(SEM_NAME);
63201715Sdavidxu	s = sem_open(SEM_NAME, O_CREAT, 0777, 0);
64201575Sdavidxu	if (s == SEM_FAILED)
65201575Sdavidxu		err(1, "sem_open failed");
66201715Sdavidxu	s2 = sem_open(SEM_NAME, O_CREAT, 0777, 0);
67201575Sdavidxu	if (s2 == SEM_FAILED)
68201575Sdavidxu		err(2, "second sem_open call failed");
69201575Sdavidxu	if (s != s2)
70205149Skib		errx(3,
71205151Skib"two sem_open calls for same semaphore do not return same address");
72201575Sdavidxu	if (sem_close(s2))
73201575Sdavidxu		err(4, "sem_close failed");
74201575Sdavidxu	if ((pid = fork()) == 0) {
75201575Sdavidxu		printf("child: sem_wait()\n");
76201575Sdavidxu		if (sem_wait(s))
77201575Sdavidxu			err(5, "sem_wait failed");
78201575Sdavidxu		printf("child: sem_wait() returned\n");
79201575Sdavidxu		exit(0);
80201575Sdavidxu	} else {
81201575Sdavidxu		sleep(1);
82201575Sdavidxu		printf("parent: sem_post()\n");
83201575Sdavidxu		if (sem_post(s))
84201575Sdavidxu			err(6, "sem_post failed");
85201575Sdavidxu		waitpid(pid, &status, 0);
86201575Sdavidxu		if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
87201575Sdavidxu			printf("OK.\n");
88201575Sdavidxu		else
89201575Sdavidxu			printf("Failure.");
90201575Sdavidxu	}
91201575Sdavidxu
92201575Sdavidxu	if (sem_close(s))
93201575Sdavidxu		err(7, "sem_close failed");
94201575Sdavidxu
95201575Sdavidxu	return (0);
96201575Sdavidxu}
97201575Sdavidxu
98201575Sdavidxuint
99294565Sjillestest_named2(void)
100294565Sjilles{
101294565Sjilles	sem_t *s, *s2, *s3;
102294565Sjilles
103294565Sjilles	printf("testing named process-shared semaphore, O_EXCL cases\n");
104294565Sjilles	sem_unlink(SEM_NAME);
105294565Sjilles	s = sem_open(SEM_NAME, O_CREAT | O_EXCL, 0777, 0);
106294565Sjilles	if (s == SEM_FAILED)
107294565Sjilles		err(1, "sem_open failed");
108294565Sjilles	s2 = sem_open(SEM_NAME, O_CREAT | O_EXCL, 0777, 0);
109294565Sjilles	if (s2 != SEM_FAILED)
110294565Sjilles		errx(2, "second sem_open call wrongly succeeded");
111294565Sjilles	if (errno != EEXIST)
112294565Sjilles		err(3, "second sem_open call failed with wrong errno");
113294565Sjilles
114294565Sjilles	s3 = sem_open(SEM_NAME, 0);
115294565Sjilles	if (s3 == SEM_FAILED)
116294565Sjilles		err(4, "third sem_open call failed");
117294565Sjilles	if (s != s3)
118294565Sjilles		errx(5,
119294565Sjilles"two sem_open calls for same semaphore do not return same address");
120294565Sjilles	if (sem_close(s3))
121294565Sjilles		err(6, "sem_close failed");
122294565Sjilles
123294565Sjilles	if (sem_close(s))
124294565Sjilles		err(7, "sem_close failed");
125294565Sjilles
126294565Sjilles	printf("OK.\n");
127294565Sjilles	return (0);
128294565Sjilles}
129294565Sjilles
130294565Sjillesint
131201575Sdavidxumain(void)
132201575Sdavidxu{
133201575Sdavidxu	test_unnamed();
134201575Sdavidxu	test_named();
135294565Sjilles	test_named2();
136201575Sdavidxu	return (0);
137201575Sdavidxu}
138