1 /* $NetBSD: h_exec.c,v 1.6 2011/02/16 17:57:44 pooka Exp $ */ 2 3 /* 4 * Copyright (c) 2011 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 17 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 18 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 23 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include <sys/types.h> 31 #include <sys/socket.h> 32 33 #include <netinet/in.h> 34 35 #include <err.h> 36 #include <errno.h> 37 #include <fcntl.h> 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <string.h> 41 #include <unistd.h> 42 43 #include <rump/rumpclient.h> 44 #include <rump/rump_syscalls.h> 45 46 int 47 main(int argc, char *argv[]) 48 { 49 struct sockaddr_in sin; 50 socklen_t slen; 51 int s1, s2; 52 char buf[12]; 53 char *eargv[4]; 54 char *ename; 55 extern char **environ; 56 57 if (rumpclient_init() == -1) 58 err(1, "init"); 59 60 if (argc > 1) { 61 if (strcmp(argv[1], "_didexec") == 0) { 62 rumpclient_daemon(0, 0); /* detach-me-notnot */ 63 s2 = atoi(argv[2]); 64 slen = sizeof(sin); 65 /* see below */ 66 rump_sys_accept(s2, (struct sockaddr *)&sin, &slen); 67 } 68 } 69 70 /* open and listenize two TCP4 suckets */ 71 if ((s1 = rump_sys_socket(PF_INET, SOCK_STREAM, 0)) == -1) 72 err(1, "socket 1"); 73 if ((s2 = rump_sys_socket(PF_INET, SOCK_STREAM, 0)) == -1) 74 err(1, "socket 2"); 75 76 memset(&sin, 0, sizeof(sin)); 77 sin.sin_len = sizeof(sin); 78 sin.sin_family = AF_INET; 79 sin.sin_port = htons(1234); 80 81 if (rump_sys_bind(s1, (struct sockaddr *)&sin, sizeof(sin)) == -1) 82 err(1, "bind1"); 83 sin.sin_port = htons(2345); 84 if (rump_sys_bind(s2, (struct sockaddr *)&sin, sizeof(sin)) == -1) 85 err(1, "bind2"); 86 87 if (rump_sys_listen(s1, 1) == -1) 88 err(1, "listen1"); 89 if (rump_sys_listen(s2, 1) == -1) 90 err(1, "listen2"); 91 92 if (argc == 1) { 93 rumpclient_daemon(0, 0); 94 slen = sizeof(sin); 95 /* 96 * "pause()", but conveniently gets rid of this helper 97 * since we were called with RUMPCLIENT_RETRYCONN_DIE set 98 */ 99 rump_sys_accept(s2, (struct sockaddr *)&sin, &slen); 100 } 101 102 if (argc == 3 && strcmp(argv[2], "cloexec1") == 0) { 103 if (rump_sys_fcntl(s1, F_SETFD, FD_CLOEXEC) == -1) { 104 err(1, "cloexec failed"); 105 } 106 } 107 108 sprintf(buf, "%d", s2); 109 110 if (argc == 3 && strcmp(argv[2], "vfork_please") == 0) { 111 switch (rumpclient_vfork()) { 112 case 0: 113 ename = __UNCONST("fourchette"); 114 break; 115 case -1: 116 err(1, "vfork"); 117 default: 118 ename = __UNCONST("h_ution"); 119 break; 120 } 121 } else { 122 ename = __UNCONST("h_ution"); 123 } 124 125 /* omstart! */ 126 eargv[0] = ename; 127 eargv[1] = __UNCONST("_didexec"); 128 eargv[2] = buf; 129 eargv[3] = NULL; 130 if (rumpclient_exec(argv[1], __UNCONST(eargv), environ) == -1) 131 err(1, "exec"); 132 } 133