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