xref: /freebsd/tools/regression/posixsem2/semtest.c (revision 2a63c3be158216222d89a073dcbd6a72ee4aab5a)
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