11612Stwisti/* $NetBSD: h_exec.c,v 1.6 2011/02/16 17:57:44 pooka Exp $ */ 23602Scoleenp 31612Stwisti/* 41612Stwisti * Copyright (c) 2011 The NetBSD Foundation, Inc. 51612Stwisti * All rights reserved. 61612Stwisti * 71612Stwisti * Redistribution and use in source and binary forms, with or without 81612Stwisti * modification, are permitted provided that the following conditions 91612Stwisti * are met: 101612Stwisti * 1. Redistributions of source code must retain the above copyright 111612Stwisti * notice, this list of conditions and the following disclaimer. 121612Stwisti * 2. Redistributions in binary form must reproduce the above copyright 131612Stwisti * notice, this list of conditions and the following disclaimer in the 141612Stwisti * documentation and/or other materials provided with the distribution. 151612Stwisti * 161612Stwisti * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 171612Stwisti * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 181612Stwisti * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 191612Stwisti * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 201612Stwisti * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 211612Stwisti * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 221612Stwisti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 231612Stwisti * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 241612Stwisti * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 251612Stwisti * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 261879Sstefank * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 271879Sstefank * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 281879Sstefank */ 291879Sstefank 301879Sstefank#include <sys/types.h> 311879Sstefank#include <sys/socket.h> 323879Stwisti 331612Stwisti#include <netinet/in.h> 341612Stwisti 351612Stwisti#include <err.h> 361612Stwisti#include <errno.h> 371612Stwisti#include <fcntl.h> 381612Stwisti#include <stdio.h> 391612Stwisti#include <stdlib.h> 401612Stwisti#include <string.h> 411612Stwisti#include <unistd.h> 421612Stwisti 431612Stwisti#include <rump/rumpclient.h> 441612Stwisti#include <rump/rump_syscalls.h> 451612Stwisti 461612Stwistiint 471612Stwistimain(int argc, char *argv[]) 481612Stwisti{ 491612Stwisti struct sockaddr_in sin; 501612Stwisti socklen_t slen; 511612Stwisti int s1, s2; 521612Stwisti char buf[12]; 531612Stwisti char *eargv[4]; 541612Stwisti char *ename; 551612Stwisti extern char **environ; 563879Stwisti 573879Stwisti if (rumpclient_init() == -1) 583879Stwisti err(1, "init"); 591612Stwisti 601612Stwisti if (argc > 1) { 611612Stwisti if (strcmp(argv[1], "_didexec") == 0) { 621612Stwisti rumpclient_daemon(0, 0); /* detach-me-notnot */ 631612Stwisti s2 = atoi(argv[2]); 641612Stwisti slen = sizeof(sin); 651612Stwisti /* see below */ 661612Stwisti rump_sys_accept(s2, (struct sockaddr *)&sin, &slen); 671612Stwisti } 683879Stwisti } 693602Scoleenp 701612Stwisti /* open and listenize two TCP4 suckets */ 711612Stwisti if ((s1 = rump_sys_socket(PF_INET, SOCK_STREAM, 0)) == -1) 721612Stwisti err(1, "socket 1"); 731612Stwisti if ((s2 = rump_sys_socket(PF_INET, SOCK_STREAM, 0)) == -1) 741612Stwisti err(1, "socket 2"); 751612Stwisti 761612Stwisti memset(&sin, 0, sizeof(sin)); 771612Stwisti sin.sin_len = sizeof(sin); 781612Stwisti sin.sin_family = AF_INET; 791612Stwisti sin.sin_port = htons(1234); 801612Stwisti 811612Stwisti if (rump_sys_bind(s1, (struct sockaddr *)&sin, sizeof(sin)) == -1) 821612Stwisti err(1, "bind1"); 833879Stwisti sin.sin_port = htons(2345); 843879Stwisti if (rump_sys_bind(s2, (struct sockaddr *)&sin, sizeof(sin)) == -1) 851612Stwisti err(1, "bind2"); 861612Stwisti 871612Stwisti if (rump_sys_listen(s1, 1) == -1) 881612Stwisti err(1, "listen1"); 891612Stwisti if (rump_sys_listen(s2, 1) == -1) 903879Stwisti err(1, "listen2"); 911612Stwisti 921612Stwisti if (argc == 1) { 931612Stwisti rumpclient_daemon(0, 0); 941612Stwisti slen = sizeof(sin); 951612Stwisti /* 961612Stwisti * "pause()", but conveniently gets rid of this helper 971612Stwisti * since we were called with RUMPCLIENT_RETRYCONN_DIE set 981612Stwisti */ 991612Stwisti rump_sys_accept(s2, (struct sockaddr *)&sin, &slen); 1001612Stwisti } 1011612Stwisti 1021612Stwisti if (argc == 3 && strcmp(argv[2], "cloexec1") == 0) { 1031612Stwisti if (rump_sys_fcntl(s1, F_SETFD, FD_CLOEXEC) == -1) { 1041612Stwisti err(1, "cloexec failed"); 1051612Stwisti } 1061612Stwisti } 1071612Stwisti 1081612Stwisti sprintf(buf, "%d", s2); 1091612Stwisti 1101612Stwisti if (argc == 3 && strcmp(argv[2], "vfork_please") == 0) { 1111612Stwisti switch (rumpclient_vfork()) { 1121612Stwisti case 0: 1131612Stwisti ename = __UNCONST("fourchette"); 1141612Stwisti break; 1151612Stwisti case -1: 1161612Stwisti err(1, "vfork"); 1171612Stwisti default: 1181612Stwisti ename = __UNCONST("h_ution"); 1191612Stwisti break; 1201612Stwisti } 1211612Stwisti } else { 1221612Stwisti ename = __UNCONST("h_ution"); 1231612Stwisti } 1241612Stwisti 1251612Stwisti /* omstart! */ 1261612Stwisti eargv[0] = ename; 1271612Stwisti eargv[1] = __UNCONST("_didexec"); 1281612Stwisti eargv[2] = buf; 1291612Stwisti eargv[3] = NULL; 1301612Stwisti if (rumpclient_exec(argv[1], __UNCONST(eargv), environ) == -1) 1311612Stwisti err(1, "exec"); 1321612Stwisti} 1331612Stwisti