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