2 * Copyright (C) 2013-2014 Robin Gareus <robin@gareus.org>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #define STDIN_FILENO 0
29 #define STDOUT_FILENO 1
32 #define STDERR_FILENO 2
35 extern char **environ;
36 static void close_fd (int *fd) { if ((*fd) >= 0) close (*fd); *fd = -1; }
38 int main(int argc, char *argv[]) {
40 // TODO: if argv > 3, assume pok[] is given, notifify parent.
41 // usage() and a man-page (help2man) would not be bad, either :)
49 pok[0] = atoi(argv[1]);
50 pok[1] = atoi(argv[2]);
51 pin[0] = atoi(argv[3]);
52 pin[1] = atoi(argv[4]);
53 pout[0] = atoi(argv[5]);
54 pout[1] = atoi(argv[6]);
56 int stderr_mode = atoi(argv[7]);
57 int nicelevel = atoi(argv[8]);
59 /* vfork()ed child process - exec external process */
61 fcntl(pok[1], F_SETFD, FD_CLOEXEC);
64 if (pin[0] != STDIN_FILENO) {
65 dup2(pin[0], STDIN_FILENO);
69 if (pout[1] != STDOUT_FILENO) {
70 dup2(pout[1], STDOUT_FILENO);
73 if (stderr_mode == 2) {
74 /* merge STDERR into output */
75 if (pout[1] != STDERR_FILENO) {
76 dup2(pout[1], STDERR_FILENO);
78 } else if (stderr_mode == 1) {
85 if (pout[1] != STDOUT_FILENO && pout[1] != STDERR_FILENO) {
93 /* copy current environment */
96 envp = (char **) calloc(1, sizeof(char*));
97 for (i=0;environ[i];++i) {
98 envp[i] = strdup(environ[i]);
99 envp = (char **) realloc(envp, (i+2) * sizeof(char*));
104 sigset(SIGPIPE, SIG_DFL);
106 signal(SIGPIPE, SIG_DFL);
110 execve(argv[9], &argv[9], envp);
112 /* if we reach here something went wrong.. */
114 (void) write(pok[1], &buf, 1 );
117 #ifdef __clang_analyzer__
118 // the clang static analyzer warns about a memleak here,
119 // but we don't care. The OS will clean up after us in a jiffy.
120 for (i=0; envp && envp[i]; ++i) {