]> granicus.if.org Git - sudo/commitdiff
Implement background mode. If I/O logging we use pipes instead of a pty.
authorTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 9 Jun 2010 20:20:04 +0000 (16:20 -0400)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 9 Jun 2010 20:20:04 +0000 (16:20 -0400)
--HG--
branch : 1.7

exec.c
exec_pty.c
sudo.c
sudo.h

diff --git a/exec.c b/exec.c
index 4cb521892fd515617c9d14ba57e03956031f32a2..d075d48fab2d64fd286944f0cfbf0c312776be8c 100644 (file)
--- 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;
     }
index ccea5dc3fafca297f44e788a1f38baa08c148dd8..06c83c389b7c314ba8bf4eefa01291692e85c7c7 100644 (file)
@@ -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 c9b1d9acfb4ac13eb5dfd662e3bec0b441ac85ae..158485211411661c387e2d8bba92e0a46ad91506 100644 (file)
--- 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 059dcd4381215b57c9e7bc6ce7e77871e1b552ec..0155372356c8060eb59e21c79dd132c73d39f576 100644 (file)
--- 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 */