xref: /netbsd-src/tests/lib/librumpclient/h_exec.c (revision 506971ff58c130f512700bb67574a7e2fdcd2f8c)
1*506971ffSandvar /*	$NetBSD: h_exec.c,v 1.7 2023/08/03 20:45:50 andvar Exp $	*/
2fd59a0e4Spooka 
3fd59a0e4Spooka /*
4fd59a0e4Spooka  * Copyright (c) 2011 The NetBSD Foundation, Inc.
5fd59a0e4Spooka  * All rights reserved.
6fd59a0e4Spooka  *
7fd59a0e4Spooka  * Redistribution and use in source and binary forms, with or without
8fd59a0e4Spooka  * modification, are permitted provided that the following conditions
9fd59a0e4Spooka  * are met:
10fd59a0e4Spooka  * 1. Redistributions of source code must retain the above copyright
11fd59a0e4Spooka  *    notice, this list of conditions and the following disclaimer.
12fd59a0e4Spooka  * 2. Redistributions in binary form must reproduce the above copyright
13fd59a0e4Spooka  *    notice, this list of conditions and the following disclaimer in the
14fd59a0e4Spooka  *    documentation and/or other materials provided with the distribution.
15fd59a0e4Spooka  *
16fd59a0e4Spooka  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17fd59a0e4Spooka  * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18fd59a0e4Spooka  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19fd59a0e4Spooka  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20fd59a0e4Spooka  * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21fd59a0e4Spooka  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22fd59a0e4Spooka  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23fd59a0e4Spooka  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24fd59a0e4Spooka  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25fd59a0e4Spooka  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26fd59a0e4Spooka  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27fd59a0e4Spooka  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28fd59a0e4Spooka  */
29fd59a0e4Spooka 
30fd59a0e4Spooka #include <sys/types.h>
31fd59a0e4Spooka #include <sys/socket.h>
32fd59a0e4Spooka 
33fd59a0e4Spooka #include <netinet/in.h>
34fd59a0e4Spooka 
35fd59a0e4Spooka #include <err.h>
36fd59a0e4Spooka #include <errno.h>
37fd59a0e4Spooka #include <fcntl.h>
38fd59a0e4Spooka #include <stdio.h>
39fd59a0e4Spooka #include <stdlib.h>
40fd59a0e4Spooka #include <string.h>
41fd59a0e4Spooka #include <unistd.h>
42fd59a0e4Spooka 
439f22773cSpooka #include <rump/rumpclient.h>
449f22773cSpooka #include <rump/rump_syscalls.h>
45fd59a0e4Spooka 
46fd59a0e4Spooka int
main(int argc,char * argv[])47fd59a0e4Spooka main(int argc, char *argv[])
48fd59a0e4Spooka {
49fd59a0e4Spooka 	struct sockaddr_in sin;
50fd59a0e4Spooka 	socklen_t slen;
51fd59a0e4Spooka 	int s1, s2;
52fd59a0e4Spooka 	char buf[12];
539f22773cSpooka 	char *eargv[4];
54daf96a00Spooka 	char *ename;
559f22773cSpooka 	extern char **environ;
569f22773cSpooka 
579f22773cSpooka 	if (rumpclient_init() == -1)
589f22773cSpooka 		err(1, "init");
59fd59a0e4Spooka 
60fd59a0e4Spooka 	if (argc > 1) {
61fd59a0e4Spooka 		if (strcmp(argv[1], "_didexec") == 0) {
621a011130Spooka 			rumpclient_daemon(0, 0); /* detach-me-notnot */
6336823968Spooka 			s2 = atoi(argv[2]);
64fd59a0e4Spooka 			slen = sizeof(sin);
65fd59a0e4Spooka 			/* see below */
669f22773cSpooka 			rump_sys_accept(s2, (struct sockaddr *)&sin, &slen);
67fd59a0e4Spooka 		}
68fd59a0e4Spooka 	}
69fd59a0e4Spooka 
70*506971ffSandvar 	/* open and listenize two TCP4 sockets */
719f22773cSpooka 	if ((s1 = rump_sys_socket(PF_INET, SOCK_STREAM, 0)) == -1)
72fd59a0e4Spooka 		err(1, "socket 1");
739f22773cSpooka 	if ((s2 = rump_sys_socket(PF_INET, SOCK_STREAM, 0)) == -1)
74fd59a0e4Spooka 		err(1, "socket 2");
75fd59a0e4Spooka 
76fd59a0e4Spooka 	memset(&sin, 0, sizeof(sin));
77fd59a0e4Spooka 	sin.sin_len = sizeof(sin);
78fd59a0e4Spooka 	sin.sin_family = AF_INET;
79fd59a0e4Spooka 	sin.sin_port = htons(1234);
80fd59a0e4Spooka 
819f22773cSpooka 	if (rump_sys_bind(s1, (struct sockaddr *)&sin, sizeof(sin)) == -1)
82fd59a0e4Spooka 		err(1, "bind1");
83fd59a0e4Spooka 	sin.sin_port = htons(2345);
849f22773cSpooka 	if (rump_sys_bind(s2, (struct sockaddr *)&sin, sizeof(sin)) == -1)
85fd59a0e4Spooka 		err(1, "bind2");
86fd59a0e4Spooka 
879f22773cSpooka 	if (rump_sys_listen(s1, 1) == -1)
88fd59a0e4Spooka 		err(1, "listen1");
899f22773cSpooka 	if (rump_sys_listen(s2, 1) == -1)
90fd59a0e4Spooka 		err(1, "listen2");
91fd59a0e4Spooka 
92fd59a0e4Spooka 	if (argc == 1) {
931a011130Spooka 		rumpclient_daemon(0, 0);
94fd59a0e4Spooka 		slen = sizeof(sin);
95fd59a0e4Spooka 		/*
96fd59a0e4Spooka 		 * "pause()", but conveniently gets rid of this helper
97fd59a0e4Spooka 		 * since we were called with RUMPCLIENT_RETRYCONN_DIE set
98fd59a0e4Spooka 		 */
999f22773cSpooka 		rump_sys_accept(s2, (struct sockaddr *)&sin, &slen);
10036823968Spooka 	}
10136823968Spooka 
10236823968Spooka 	if (argc == 3 && strcmp(argv[2], "cloexec1") == 0) {
1039f22773cSpooka 		if (rump_sys_fcntl(s1, F_SETFD, FD_CLOEXEC) == -1) {
10436823968Spooka 			err(1, "cloexec failed");
10536823968Spooka 		}
106fd59a0e4Spooka 	}
107fd59a0e4Spooka 
1081a011130Spooka 	sprintf(buf, "%d", s2);
1091a011130Spooka 
1101a011130Spooka 	if (argc == 3 && strcmp(argv[2], "vfork_please") == 0) {
1111a011130Spooka 		switch (rumpclient_vfork()) {
1121a011130Spooka 		case 0:
1131a011130Spooka 			ename = __UNCONST("fourchette");
1141a011130Spooka 			break;
1151a011130Spooka 		case -1:
1161a011130Spooka 			err(1, "vfork");
1171a011130Spooka 		default:
118daf96a00Spooka 			ename = __UNCONST("h_ution");
1191a011130Spooka 			break;
1201a011130Spooka 		}
1211a011130Spooka 	} else {
1221a011130Spooka 		ename = __UNCONST("h_ution");
1231a011130Spooka 	}
124daf96a00Spooka 
125fd59a0e4Spooka 	/* omstart! */
126daf96a00Spooka 	eargv[0] = ename;
1279f22773cSpooka 	eargv[1] = __UNCONST("_didexec");
1289f22773cSpooka 	eargv[2] = buf;
1299f22773cSpooka 	eargv[3] = NULL;
1309f22773cSpooka 	if (rumpclient_exec(argv[1], __UNCONST(eargv), environ) == -1)
131fd59a0e4Spooka 		err(1, "exec");
132fd59a0e4Spooka }
133