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