]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - tools/test/posixshm/shm_test.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / tools / test / posixshm / shm_test.c
1 /*
2  * Test the POSIX shared-memory API.
3  * Dedicated to the public domain by Garrett A. Wollman, 2000.
4  * $FreeBSD$
5  */
6
7 #include <sys/types.h>
8 #include <sys/mman.h>
9 #include <sys/wait.h>
10
11 #include <err.h>
12 #include <errno.h>
13 #include <fcntl.h>
14 #include <signal.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <unistd.h>
19
20 /*
21  * Signal handler which does nothing.
22  */
23 static void 
24 ignoreit(int sig __unused)
25 {
26         ;
27 }
28
29 int
30 main(int argc, char **argv)
31 {
32         char buf[1024], *cp, c;
33         int error, desc, rv;
34         long scval;
35         sigset_t ss;
36         struct sigaction sa;
37         void *region;
38         size_t i, psize;
39
40 #ifndef _POSIX_SHARED_MEMORY_OBJECTS
41         printf("_POSIX_SHARED_MEMORY_OBJECTS is undefined\n");
42 #else
43         printf("_POSIX_SHARED_MEMORY_OBJECTS is defined as %ld\n", 
44                (long)_POSIX_SHARED_MEMORY_OBJECTS - 0);
45         if (_POSIX_SHARED_MEMORY_OBJECTS - 0 == -1)
46                 printf("***Indicates this feature may be unsupported!\n");
47 #endif
48         errno = 0;
49         scval = sysconf(_SC_SHARED_MEMORY_OBJECTS);
50         if (scval == -1 && errno != 0) {
51                 err(1, "sysconf(_SC_SHARED_MEMORY_OBJECTS)");
52         } else {
53                 printf("sysconf(_SC_SHARED_MEMORY_OBJECTS) returns %ld\n",
54                        scval);
55                 if (scval == -1)
56                         printf("***Indicates this feature is unsupported!\n");
57         }
58
59         errno = 0;
60         scval = sysconf(_SC_PAGESIZE);
61         if (scval == -1 && errno != 0) {
62                 err(1, "sysconf(_SC_PAGESIZE)");
63         } else if (scval <= 0 || (size_t)psize != psize) {
64                 warnx("bogus return from sysconf(_SC_PAGESIZE): %ld",
65                       scval);
66                 psize = 4096;
67         } else {
68                 printf("sysconf(_SC_PAGESIZE) returns %ld\n", scval);
69                 psize = scval;
70         }
71
72         argc--, argv++;
73
74         if (*argv) {
75                 strncat(buf, *argv, (sizeof buf) - 1);
76                 desc = shm_open(buf, O_EXCL | O_CREAT | O_RDWR, 0600);
77         } else {
78                 do {
79                         /*
80                          * Can't use mkstemp for obvious reasons...
81                          */
82                         strcpy(buf, "/tmp/shmtest.XXXXXXXXXXXX");
83                         mktemp(buf);
84                         desc = shm_open(buf, O_EXCL | O_CREAT | O_RDWR, 0600);
85                 } while (desc < 0 && errno == EEXIST);
86         }
87
88         if (desc < 0)
89                 err(1, "shm_open");
90
91         if (shm_unlink(buf) < 0)
92                 err(1, "shm_unlink");
93
94         if (ftruncate(desc, (off_t)psize) < 0)
95                 err(1, "ftruncate");
96
97         region = mmap((void *)0, psize, PROT_READ | PROT_WRITE, MAP_SHARED,
98                       desc, (off_t)0);
99         if (region == MAP_FAILED)
100                 err(1, "mmap");
101         memset(region, '\377', psize);
102
103         sa.sa_flags = 0;
104         sa.sa_handler = ignoreit;
105         sigemptyset(&sa.sa_mask);
106         if (sigaction(SIGUSR1, &sa, (struct sigaction *)0) < 0)
107                 err(1, "sigaction");
108
109         sigemptyset(&ss);
110         sigaddset(&ss, SIGUSR1);
111         if (sigprocmask(SIG_BLOCK, &ss, (sigset_t *)0) < 0)
112                 err(1, "sigprocmask");
113
114         rv = fork();
115         if (rv < 0) {
116                 err(1, "fork");
117         } else if (rv == 0) {
118                 sigemptyset(&ss);
119                 sigsuspend(&ss);
120
121                 for (cp = region; cp < (char *)region + psize; cp++) {
122                         if (*cp != '\151')
123                                 _exit(1);
124                 }
125                 if (lseek(desc, 0, SEEK_SET) == -1)
126                         _exit(1);
127                 for (i = 0; i < psize; i++) {
128                         error = read(desc, &c, 1);
129                         if (c != '\151')
130                                 _exit(1);
131                 }
132                 _exit(0);
133         } else {
134                 int status;
135
136                 memset(region, '\151', psize - 2);
137                 error = pwrite(desc, region, 2, psize - 2);
138                 if (error != 2) {
139                         if (error >= 0)
140                                 errx(1, "short write %d", error);
141                         else
142                                 err(1, "shmfd write");
143                 }
144                 kill(rv, SIGUSR1);
145                 waitpid(rv, &status, 0);
146
147                 if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
148                         printf("Functionality test successful\n");
149                         exit(0);
150                 } else if (WIFEXITED(status)) {
151                         printf("Child process exited with status %d\n",
152                                WEXITSTATUS(status));
153                 } else {
154                         printf("Child process terminated with %s\n",
155                                strsignal(WTERMSIG(status)));
156                 }
157         }
158         exit(1);
159 }