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