1146574Sharti/*- 2146574Sharti * Copyright (C) 2005 Max Okumoto. 3146574Sharti * All rights reserved. 4146574Sharti * 5146574Sharti * Redistribution and use in source and binary forms, with or without 6146574Sharti * modification, are permitted provided that the following conditions 7146574Sharti * are met: 8146574Sharti * 1. Redistributions of source code must retain the above copyright 9146574Sharti * notice, this list of conditions and the following disclaimer. 10146574Sharti * 2. Redistributions in binary form must reproduce the above copyright 11146574Sharti * notice, this list of conditions and the following disclaimer in the 12146574Sharti * documentation and/or other materials provided with the distribution. 13146574Sharti * 14146574Sharti * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15146574Sharti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16146574Sharti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17146574Sharti * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 18146574Sharti * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19146574Sharti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20146574Sharti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21146574Sharti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22146574Sharti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23146574Sharti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24146574Sharti * SUCH DAMAGE. 25146574Sharti */ 26146574Sharti 27146574Sharti#include <sys/cdefs.h> 28146574Sharti__FBSDID("$FreeBSD$"); 29146574Sharti 30146574Sharti#include <unistd.h> 31146574Sharti#include <errno.h> 32146574Sharti#include <stdlib.h> 33146574Sharti#include <string.h> 34146574Sharti#include <fcntl.h> 35146574Sharti 36146574Sharti#include "proc.h" 37146574Sharti#include "shell.h" 38146574Sharti#include "util.h" 39146574Sharti 40146574Sharti/** 41146574Sharti * Replace the current process. 42146574Sharti */ 43146574Shartivoid 44146574ShartiProc_Exec(const ProcStuff *ps) 45146574Sharti{ 46146574Sharti 47146574Sharti if (ps->in != STDIN_FILENO) { 48146574Sharti /* 49146574Sharti * Redirect the child's stdin to the input fd 50146574Sharti * and reset it to the beginning (again). 51146574Sharti */ 52146574Sharti if (dup2(ps->in, STDIN_FILENO) == -1) 53146574Sharti Punt("Cannot dup2: %s", strerror(errno)); 54146574Sharti lseek(STDIN_FILENO, (off_t)0, SEEK_SET); 55146574Sharti } 56146574Sharti 57146574Sharti if (ps->out != STDOUT_FILENO) { 58146574Sharti /* 59146574Sharti * Redirect the child's stdout to the output fd. 60146574Sharti */ 61146574Sharti if (dup2(ps->out, STDOUT_FILENO) == -1) 62146574Sharti Punt("Cannot dup2: %s", strerror(errno)); 63146574Sharti close(ps->out); 64146574Sharti } 65146574Sharti 66146574Sharti if (ps->err != STDERR_FILENO) { 67146574Sharti /* 68146574Sharti * Redirect the child's stderr to the err fd. 69146574Sharti */ 70146574Sharti if (dup2(ps->err, STDERR_FILENO) == -1) 71146574Sharti Punt("Cannot dup2: %s", strerror(errno)); 72146574Sharti close(ps->err); 73146574Sharti } 74146574Sharti 75146574Sharti if (ps->merge_errors) { 76146574Sharti /* 77146574Sharti * Send stderr to parent process too. 78146574Sharti */ 79146574Sharti if (dup2(STDOUT_FILENO, STDERR_FILENO) == -1) 80146574Sharti Punt("Cannot dup2: %s", strerror(errno)); 81146574Sharti } 82146574Sharti 83146574Sharti if (commandShell->unsetenv) { 84146574Sharti /* for the benfit of ksh */ 85146574Sharti unsetenv("ENV"); 86146574Sharti } 87146574Sharti 88146574Sharti /* 89146574Sharti * The file descriptors for stdin, stdout, or stderr might 90146574Sharti * have been marked close-on-exec. Clear the flag on all 91146574Sharti * of them. 92146574Sharti */ 93146574Sharti fcntl(STDIN_FILENO, F_SETFD, 94146574Sharti fcntl(STDIN_FILENO, F_GETFD) & (~FD_CLOEXEC)); 95146574Sharti fcntl(STDOUT_FILENO, F_SETFD, 96146574Sharti fcntl(STDOUT_FILENO, F_GETFD) & (~FD_CLOEXEC)); 97146574Sharti fcntl(STDERR_FILENO, F_SETFD, 98146574Sharti fcntl(STDERR_FILENO, F_GETFD) & (~FD_CLOEXEC)); 99146574Sharti 100146574Sharti if (ps->pgroup) { 101146574Sharti#ifdef USE_PGRP 102146574Sharti /* 103146574Sharti * Become a process group leader, so we can kill it and all 104146574Sharti * its descendants in one fell swoop, by killing its process 105146574Sharti * family, but not commit suicide. 106146574Sharti */ 107146574Sharti#if defined(SYSV) 108146574Sharti setsid(); 109146574Sharti#else 110146574Sharti setpgid(0, getpid()); 111146574Sharti#endif 112146574Sharti#endif /* USE_PGRP */ 113146574Sharti } 114146574Sharti 115146574Sharti if (ps->searchpath) { 116146574Sharti execvp(ps->argv[0], ps->argv); 117146574Sharti 118146574Sharti write(STDERR_FILENO, ps->argv[0], strlen(ps->argv[0])); 119200120Sstefanf write(STDERR_FILENO, ": ", 2); 120146574Sharti write(STDERR_FILENO, strerror(errno), strlen(strerror(errno))); 121146574Sharti write(STDERR_FILENO, "\n", 1); 122146574Sharti } else { 123146574Sharti execv(commandShell->path, ps->argv); 124146574Sharti 125146574Sharti write(STDERR_FILENO, 126146574Sharti "Could not execute shell\n", 127146574Sharti sizeof("Could not execute shell")); 128146574Sharti } 129146574Sharti 130146574Sharti /* 131146574Sharti * Since we are the child process, exit without flushing buffers. 132146574Sharti */ 133146574Sharti _exit(1); 134146574Sharti} 135