From: Todd C. Miller Date: Sat, 8 Aug 2009 12:55:43 +0000 (+0000) Subject: Fix detection of the child process exiting. Since the child is in X-Git-Tag: SUDO_1_7_3~335 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=40a21a6c75e1916a9d6656526d9032d1813e03ee;p=sudo Fix detection of the child process exiting. Since the child is in its own session we should only ever get SIGCHLD for that process but better safe than sorry. --- diff --git a/script.c b/script.c index 8a9f928b4..db55926f8 100644 --- a/script.c +++ b/script.c @@ -79,6 +79,8 @@ int script_fds[5]; static sig_atomic_t alive = 1; +static pid_t child; + static void script_child __P((const char *path, char *const argv[])); static void sync_winsize __P((int src, int dst)); static void sigchild __P((int signo)); @@ -88,9 +90,14 @@ static int get_pty __P((int *master, int *slave)); /* * TODO: run monitor as root? * if stdin not tty, just use sane defaults - * fix sigchild */ +struct script_buf { + int len; /* buffer length (how much read in) */ + int off; /* write position (how much already consumed) */ + char buf[16 * 1024]; +}; + static int fdcompar(v1, v2) const void *v1; @@ -119,26 +126,6 @@ script_setup() if (!term_raw(STDIN_FILENO)) log_error(USE_ERRNO, "Can't set terminal to raw mode"); -#if 0 - if (openpty(&script_fds[SFD_MASTER], &script_fds[SFD_SLAVE], ttypath, oterm, &win) == -1) - log_error(USE_ERRNO, "Can't get pty"); - - /* Get current terminal attrs, set stdin to raw, no echo, then open pty. */ - if (tcgetattr(STDIN_FILENO, &oterm_buf) != 0) - log_error(USE_ERRNO, "Can't get terminal attributes"); - oterm = &oterm_buf; - memcpy(&term, oterm, sizeof(term)); - cfmakeraw(&term); - term.c_lflag &= ~ECHO; - if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &term) != 0) - log_error(USE_ERRNO, "Can't set terminal attributes"); - if (ioctl(STDIN_FILENO, TIOCGWINSZ, &win) != 0) - log_error(USE_ERRNO, "Can't get window size"); - if (openpty(&script_fds[SFD_MASTER], &script_fds[SFD_SLAVE], ttypath, oterm, &win) == -1) - log_error(USE_ERRNO, "Can't open pty"); - (void) chown(ttypath, runas_pw->pw_uid, -1); -#endif - /* * Log files live in a per-user subdir of _PATH_SUDO_SESSDIR. * Create these if they don't already exist. @@ -185,18 +172,11 @@ script_setup() qsort(script_fds, 5, sizeof(int), fdcompar); } -struct script_buf { - int len; /* buffer length (how much read in) */ - int off; /* write position (how much already consumed) */ - char buf[16 * 1024]; -}; - int script_execv(path, argv) const char *path; char *const argv[]; { - pid_t child, pid; int n, nready; fd_set *fdsr, *fdsw; struct script_buf input, output; @@ -371,13 +351,6 @@ script_execv(path, argv) } term_restore(STDIN_FILENO); - do { -#ifdef sudo_waitpid - pid = sudo_waitpid(child, &n, 0); -#else - pid = wait(&n); -#endif - } while (pid != -1 || errno == EINTR); #ifdef HAVE_VHANGUP signal(SIGHUP, SIG_IGN); vhangup(); @@ -447,8 +420,23 @@ static void sigchild(signo) int signo; { - /* XXX - might not be right pid, must wait for it to find out */ + int status; + pid_t pid; + +#ifdef sudo_waitpid + do { + pid = sudo_waitpid(child, &status, WNOHANG); + if (pid == child) { + alive = 0; + break; + } + } while (pid > 0 || (pid == -1 && errno == EINTR)); +#else + do { + pid = wait(); + } while (pid == -1 && errno == EINTR); alive = 0; +#endif } static void