]> granicus.if.org Git - sudo/commitdiff
In handle_sigchld() fix the return value when we've already received
authorTodd C. Miller <Todd.Miller@courtesan.com>
Thu, 9 Jun 2016 16:50:58 +0000 (10:50 -0600)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Thu, 9 Jun 2016 16:50:58 +0000 (10:50 -0600)
an exec error.  We don't want to overwrite the error status but we
do need to indicate that the command is no longer running.
Fixes as hang on execve(2) error when running in a pty.

src/exec_pty.c

index 3437e27721483a4c37fee80b1d3182c1d05ce7a8..b3a4e3802e8fe56ee125dee7521f184c2267e3e2 100644 (file)
@@ -1156,7 +1156,10 @@ handle_sigchld(int backchannel, struct command_status *cstat)
     do {
        pid = waitpid(cmnd_pid, &status, WUNTRACED|WNOHANG);
     } while (pid == -1 && errno == EINTR);
-    if (pid == cmnd_pid) {
+    if (pid != cmnd_pid) {
+       sudo_debug_printf(SUDO_DEBUG_INFO,
+           "waitpid returned %d, expected pid %d", pid, cmnd_pid);
+    } else {
        if (cstat->type != CMD_ERRNO) {
            char signame[SIG2STR_MAX];
 
@@ -1174,7 +1177,7 @@ handle_sigchld(int backchannel, struct command_status *cstat)
                if (pid != mon_pgrp)
                    cmnd_pgrp = pid;
                if (send_status(backchannel, cstat) == -1)
-                   return alive; /* XXX */
+                   debug_return_bool(alive); /* XXX */
            } else if (WIFSIGNALED(status)) {
                if (sig2str(WTERMSIG(status), signame) == -1)
                    snprintf(signame, sizeof(signame), "%d", WTERMSIG(status));
@@ -1184,9 +1187,9 @@ handle_sigchld(int backchannel, struct command_status *cstat)
                sudo_debug_printf(SUDO_DEBUG_INFO, "command exited: %d",
                    WEXITSTATUS(status));
            }
-           if (!WIFSTOPPED(status))
-               alive = false;
        }
+       if (!WIFSTOPPED(status))
+           alive = false;
     }
     debug_return_bool(alive);
 }
@@ -1253,6 +1256,8 @@ mon_errpipe_cb(int fd, int what, void *v)
        }
     } else {
        /* Got errno or EOF, either way we are done with errpipe. */
+       sudo_debug_printf(SUDO_DEBUG_DIAG, "%s: type: %d, val: %d",
+           __func__, mc->cstat->type, mc->cstat->val);
        sudo_ev_del(mc->evbase, mc->errpipe_event);
        close(fd);
     }