]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/netbsd-tests/rump/rumpkern/h_client/h_forkcli.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / netbsd-tests / rump / rumpkern / h_client / h_forkcli.c
1 /*      $NetBSD: h_forkcli.c,v 1.1 2011/01/05 17:19:09 pooka Exp $      */
2
3 #include <sys/types.h>
4 #include <sys/wait.h>
5
6 #include <err.h>
7 #include <errno.h>
8 #include <fcntl.h>
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <unistd.h>
13
14 #include <rump/rump_syscalls.h>
15 #include <rump/rumpclient.h>
16
17 static void
18 simple(void)
19 {
20         struct rumpclient_fork *rf;
21         pid_t pid1, pid2;
22         int fd, status;
23
24         if ((pid1 = rump_sys_getpid()) < 2)
25                 errx(1, "unexpected pid %d", pid1);
26
27         fd = rump_sys_open("/dev/null", O_CREAT | O_RDWR);
28         if (rump_sys_write(fd, &fd, sizeof(fd)) != sizeof(fd))
29                 errx(1, "write newlyopened /dev/null");
30
31         if ((rf = rumpclient_prefork()) == NULL)
32                 err(1, "prefork");
33
34         switch (fork()) {
35         case -1:
36                 err(1, "fork");
37                 break;
38         case 0:
39                 if (rumpclient_fork_init(rf) == -1)
40                         err(1, "postfork init failed");
41
42                 if ((pid2 = rump_sys_getpid()) < 2)
43                         errx(1, "unexpected pid %d", pid2);
44                 if (pid1 == pid2)
45                         errx(1, "child and parent pids are equal");
46
47                 /* check that we can access the fd, the close it and exit */
48                 if (rump_sys_write(fd, &fd, sizeof(fd)) != sizeof(fd))
49                         errx(1, "write child /dev/null");
50                 rump_sys_close(fd);
51                 break;
52         default:
53                 /*
54                  * check that we can access the fd, wait for the child, and
55                  * check we can still access the fd
56                  */
57                 if (rump_sys_write(fd, &fd, sizeof(fd)) != sizeof(fd))
58                         errx(1, "write parent /dev/null");
59                 if (wait(&status) == -1)
60                         err(1, "wait failed");
61                 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
62                         errx(1, "child exited with status %d", status);
63                 if (rump_sys_write(fd, &fd, sizeof(fd)) != sizeof(fd))
64                         errx(1, "write parent /dev/null");
65                 break;
66         }
67 }
68
69 static void
70 cancel(void)
71 {
72
73         /* XXX: not implemented in client / server !!! */
74 }
75
76 #define TESTSTR "i am your fatherrrrrrr"
77 #define TESTSLEN (sizeof(TESTSTR)-1)
78 static void
79 pipecomm(void)
80 {
81         struct rumpclient_fork *rf;
82         char buf[TESTSLEN+1];
83         int pipetti[2];
84         int status;
85
86         if (rump_sys_pipe(pipetti) == -1)
87                 errx(1, "pipe");
88
89         if ((rf = rumpclient_prefork()) == NULL)
90                 err(1, "prefork");
91
92         switch (fork()) {
93         case -1:
94                 err(1, "fork");
95                 break;
96         case 0:
97                 if (rumpclient_fork_init(rf) == -1)
98                         err(1, "postfork init failed");
99
100                 memset(buf, 0, sizeof(buf));
101                 if (rump_sys_read(pipetti[0], buf, TESTSLEN) != TESTSLEN)
102                         err(1, "pipe read");
103                 if (strcmp(TESTSTR, buf) != 0)
104                         errx(1, "teststring doesn't match, got %s", buf);
105                 break;
106         default:
107                 if (rump_sys_write(pipetti[1], TESTSTR, TESTSLEN) != TESTSLEN)
108                         err(1, "pipe write");
109                 if (wait(&status) == -1)
110                         err(1, "wait failed");
111                 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
112                         errx(1, "child exited with status %d", status);
113                 break;
114         }
115 }
116
117 static void
118 fakeauth(void)
119 {
120         struct rumpclient_fork *rf;
121         uint32_t *auth;
122         int rv;
123
124         if ((rf = rumpclient_prefork()) == NULL)
125                 err(1, "prefork");
126
127         /* XXX: we know the internal structure of rf */
128         auth = (void *)rf;
129         *(auth+3) = *(auth+3) ^ 0x1;
130
131         rv = rumpclient_fork_init(rf);
132         if (!(rv == -1 && errno == ESRCH))
133                 exit(1);
134 }
135
136 struct parsa {
137         const char *arg;                /* sp arg, el           */
138         void (*spring)(void);           /* spring into action   */
139 } paragus[] = {
140         { "simple", simple },
141         { "cancel", cancel },
142         { "pipecomm", pipecomm },
143         { "fakeauth", fakeauth },
144 };
145
146 int
147 main(int argc, char *argv[])
148 {
149         unsigned i;
150
151         if (argc != 2)
152                 errx(1, "invalid usage");
153
154         if (rumpclient_init() == -1)
155                 err(1, "rumpclient init");
156
157         for (i = 0; i < __arraycount(paragus); i++) {
158                 if (strcmp(argv[1], paragus[i].arg) == 0) {
159                         paragus[i].spring();
160                         break;
161                 }
162         }
163         if (i == __arraycount(paragus)) {
164                 printf("invalid test %s\n", argv[1]);
165                 exit(1);
166         }
167
168         exit(0);
169 }