From 9f14b1b80e6b09e6b2dc067704fff2034dc0ad23 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 8 Jan 2004 21:21:42 +0000 Subject: Assorted work git-svn-id: file:///home/lennart/svn/public/ivam2/trunk@18 dbf6933d-3bce-0310-9bcc-ed052ba35b35 --- src/exec.c | 123 +++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 74 insertions(+), 49 deletions(-) (limited to 'src/exec.c') diff --git a/src/exec.c b/src/exec.c index fabe757..5691c75 100644 --- a/src/exec.c +++ b/src/exec.c @@ -5,6 +5,7 @@ #include #include #include +#include #include @@ -187,42 +188,38 @@ static void *oop_read_cb(oop_source *source, int fd, oop_event event, void *user } static void pipe_close(int fds[]) { - close(fds[0]); - close(fds[1]); + if (fds[0] >= 0) + close(fds[0]); + if (fds[1] >= 0) + close(fds[1]); } -pid_t child_process_create(const char *file, char *const argv[], int *ifd, int *ofd, process_exit_cb_t cb, void *user) { +pid_t child_process_create(const char *file, char *const argv[], int *ifd, int *ofd, process_exit_cb_t cb, void *user, int pipe_hack) { pid_t pid; - int stdin_fds[2]; - int stdout_fds[2]; - int stderr_fds[2]; + int stdin_fds[2] = { -1, -1 }; + int stdout_fds[2] = { -1, -1 }; + int stderr_fds[2] = { -1, -1 }; daemon_log(LOG_INFO, "Executing child process '%s'.", file); - if (pipe(stdin_fds) < 0) { + if (ofd && pipe(stdin_fds) < 0) { daemon_log(LOG_ERR, "pipe() failed: %s", strerror(errno)); - return -1; + goto fail; } - if (pipe(stdout_fds) < 0) { + if (ifd && pipe(stdout_fds) < 0) { daemon_log(LOG_ERR, "pipe() failed: %s", strerror(errno)); - pipe_close(stdin_fds); - return -1; + goto fail; } if (pipe(stderr_fds) < 0) { daemon_log(LOG_ERR, "pipe() failed: %s", strerror(errno)); - pipe_close(stdin_fds); - pipe_close(stdout_fds); - return -1; + goto fail; } if ((pid = fork()) < 0) { daemon_log(LOG_ERR, "fork() failed: %s", strerror(errno)); - pipe_close(stdin_fds); - pipe_close(stdout_fds); - pipe_close(stderr_fds); - return -1; + goto fail; } if (pid) { @@ -240,17 +237,15 @@ pid_t child_process_create(const char *file, char *const argv[], int *ifd, int * p->stderr_pipe = stderr_fds[0]; close(stderr_fds[1]); - if (ifd) + if (ifd) { *ifd = stdout_fds[0]; - else - close(stdout_fds[0]); - close(stdout_fds[1]); + close(stdout_fds[1]); + } - if (ofd) + if (ofd) { *ofd = stdin_fds[1]; - else - close(stdin_fds[1]); - close(stdin_fds[0]); + close(stdin_fds[0]); + } assert(event_source && event_source->on_fd); event_source->on_fd(event_source, p->stderr_pipe, OOP_READ, oop_read_cb, p); @@ -261,48 +256,78 @@ pid_t child_process_create(const char *file, char *const argv[], int *ifd, int * } else { /* child */ - int fd; + int fd, efd; close(stderr_fds[0]); - close(stdout_fds[0]); - close(stdin_fds[1]); + if (ifd) { + if (pipe_hack) { + /* This might get a problem in the future, when more tahn 127 fds have been allocated */ + struct stat s; + assert(fstat(128, &s) < 0 && errno == EBADF); + + + if (dup2(stdout_fds[0], 128) < 0) { + daemon_log(LOG_ERR, "dup2() failed: %s", strerror(errno)); + exit(1); + } + } + close(stdout_fds[0]); + } + if (ofd) + close(stdin_fds[1]); - for (fd = 0; fd <= 2; fd++) { - if (fd != stderr_fds[1] && fd != stdout_fds[1] && fd != stdin_fds[0]) + for (fd = 0; fd <= 127; fd++) { + if (fd != stderr_fds[1] && (!ifd || fd != stdout_fds[1]) && (!ofd || fd != stdin_fds[0])) close(fd); } - if ((stdin_fds[0] != 0 && dup2(stdin_fds[0], 0) < 0) || - (stdout_fds[1] != 1 && dup2(stdout_fds[1], 1) < 0) || - (stderr_fds[1] != 2 && dup2(stderr_fds[1], 2) < 0)) { - daemon_log(LOG_ERR, "dup2() failed: %s", strerror(errno)); - exit(1); + if (ofd) { + if (stdin_fds[0] != 0) { + if (dup2(stdin_fds[0], 0) < 0) { + daemon_log(LOG_ERR, "dup2() failed: %s", strerror(errno)); + exit(1); + } + close(stdin_fds[0]); + } + } else { + close(0); + if (open("/dev/null", O_RDONLY) != 0) { + daemon_log(LOG_ERR, "open(\"/dev/null\") != 0: %s", strerror(errno)); + exit(1); + } } - if (stdin_fds[0] > 2) close(stdin_fds[0]); - if (stdout_fds[1] > 2) close(stdout_fds[1]); - if (stderr_fds[1] > 2) close(stderr_fds[1]); - - if (!ifd) { - close(1); - if (open("/dev/null", O_WRONLY) != 1) { - daemon_log(LOG_ERR, "open(\"/dev/null\") failed: %s", strerror(errno)); + efd = ifd ? stdout_fds[1] : stderr_fds[1]; + if (efd != 1) { + if (dup2(efd, 1) < 0) { + daemon_log(LOG_ERR, "dup2() failed: %s", strerror(errno)); exit(1); } - } - if (!ofd) { - close(0); - if (open("/dev/null", O_RDONLY) != 0) { - daemon_log(LOG_ERR, "open(\"/dev/null\") failed: %s", strerror(errno)); + if (ifd) + close(stdout_fds[1]); + } + + if (stderr_fds[1] != 2){ + if (dup2(stderr_fds[1], 2) < 0) { + daemon_log(LOG_ERR, "dup2() failed: %s", strerror(errno)); exit(1); } + + close(stderr_fds[1]); } execvp(file, argv); daemon_log(LOG_ERR, "exec('%s', ...) failed: %s", file, strerror(errno)); exit(1); } + +fail: + pipe_close(stdin_fds); + pipe_close(stdout_fds); + pipe_close(stderr_fds); + + return (pid_t) -1; } -- cgit