From 6270eb96ce1247ad55d832288114b4016e3e5468 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Wed, 9 Jun 2010 16:20:04 -0400 Subject: [PATCH] Implement background mode. If I/O logging we use pipes instead of a pty. --HG-- branch : 1.7 --- exec.c | 24 ++++++++++++++++++++---- exec_pty.c | 9 +++++---- sudo.c | 17 ++--------------- sudo.h | 2 +- 4 files changed, 28 insertions(+), 24 deletions(-) diff --git a/exec.c b/exec.c index 4cb521892..d075d48fa 100644 --- a/exec.c +++ b/exec.c @@ -136,27 +136,43 @@ static int fork_cmnd(path, argv, envp, sv, rbac_enabled) * we fact that we have two different controlling terminals to deal with. */ int -sudo_execve(path, argv, envp, uid, cstat, dowait) +sudo_execve(path, argv, envp, uid, cstat, dowait, bgmode) const char *path; char *argv[]; char *envp[]; uid_t uid; struct command_status *cstat; int dowait; + int bgmode; { sigaction_t sa; fd_set *fdsr, *fdsw; int maxfd, n, nready, status, sv[2]; int rbac_enabled = 0; - int log_io = 0; + int log_io; pid_t child; - cstat->type = CMD_INVALID; + /* If running in background mode, fork and exit. */ + if (bgmode) { + switch (fork()) { + case -1: + cstat->type = CMD_ERRNO; + cstat->val = errno; + return -1; + case 0: + /* child continues */ + break; + default: + /* parent exits */ + exit(0); + } + } #ifdef _PATH_SUDO_IO_LOGDIR log_io = def_log_output || def_log_input || def_use_pty; if (log_io) { - pty_setup(uid); + if (!bgmode) + pty_setup(uid); io_log_open(); dowait = TRUE; } diff --git a/exec_pty.c b/exec_pty.c index ccea5dc3f..06c83c389 100644 --- a/exec_pty.c +++ b/exec_pty.c @@ -195,7 +195,8 @@ suspend_parent(signo) /* Suspend self and continue child when we resume. */ sa.sa_handler = SIG_DFL; sigaction(signo, &sa, &osa); - killpg(ppgrp, signo); + if (killpg(ppgrp, signo) != 0) + warning("killpg(%d, %d)", ppgrp, signo); /* Check foreground/background status on resume. */ check_foreground(); @@ -388,7 +389,7 @@ fork_pty(path, argv, envp, sv, rbac_enabled, maxfd) * to interpose ourselves instead of duping the pty fd. */ memset(io_pipe, 0, sizeof(io_pipe)); - if (!isatty(STDIN_FILENO)) { + if (io_fds[SFD_STDIN] == -1 || !isatty(STDIN_FILENO)) { pipeline = TRUE; if (pipe(io_pipe[STDIN_FILENO]) != 0) error(1, "unable to create pipe"); @@ -396,7 +397,7 @@ fork_pty(path, argv, envp, sv, rbac_enabled, maxfd) log_stdin, iobufs); io_fds[SFD_STDIN] = io_pipe[STDIN_FILENO][0]; } - if (!isatty(STDOUT_FILENO)) { + if (io_fds[SFD_STDOUT] == -1 || !isatty(STDOUT_FILENO)) { pipeline = TRUE; if (pipe(io_pipe[STDOUT_FILENO]) != 0) error(1, "unable to create pipe"); @@ -404,7 +405,7 @@ fork_pty(path, argv, envp, sv, rbac_enabled, maxfd) log_stdout, iobufs); io_fds[SFD_STDOUT] = io_pipe[STDOUT_FILENO][1]; } - if (!isatty(STDERR_FILENO)) { + if (io_fds[SFD_STDERR] == -1 || !isatty(STDERR_FILENO)) { if (pipe(io_pipe[STDERR_FILENO]) != 0) error(1, "unable to create pipe"); iobufs = io_buf_new(io_pipe[STDERR_FILENO][0], STDERR_FILENO, diff --git a/sudo.c b/sudo.c index c9b1d9acf..158485211 100644 --- a/sudo.c +++ b/sudo.c @@ -864,20 +864,6 @@ exec_setup(flags, rbac_enabled, ttyname, ttyfd) goto done; } - if (ISSET(sudo_mode, MODE_BACKGROUND)) { - switch (fork()) { - case -1: - warning("fork"); - goto done; - case 0: - /* child continues */ - break; - default: - /* parent exists */ - exit(0); - } - } - rval = TRUE; done: @@ -905,7 +891,8 @@ run_command(path, argv, envp, uid, dowait) cstat.type = CMD_INVALID; cstat.val = 0; - sudo_execve(path, argv, envp, uid, &cstat, dowait); + sudo_execve(path, argv, envp, uid, &cstat, dowait, + ISSET(sudo_mode, MODE_BACKGROUND)); switch (cstat.type) { case CMD_ERRNO: diff --git a/sudo.h b/sudo.h index 059dcd438..015537235 100644 --- a/sudo.h +++ b/sudo.h @@ -232,7 +232,7 @@ void validate_env_vars __P((struct list_member *)); /* exec.c */ int sudo_execve __P((const char *path, char *argv[], char *envp[], uid_t uid, - struct command_status *cstat, int dowait)); + struct command_status *cstat, int dowait, int bgmode)); int my_execve __P((const char *path, char *argv[], char *envp[])); /* exec_pty.c */ -- 2.40.0