diff --git a/script.c b/script.c index 2d161e8be..d40443838 100644 --- a/script.c +++ b/script.c @@ -236,7 +236,7 @@ void script_setup() { char pathbuf[PATH_MAX]; - int len, ok; + int len; script_fds[SFD_USERTTY] = open(_PATH_TTY, O_RDWR|O_NOCTTY, 0); if (script_fds[SFD_USERTTY] == -1) @@ -251,12 +251,6 @@ script_setup() log_error(USE_ERRNO, "Can't copy terminal attributes"); sync_winsize(script_fds[SFD_USERTTY], script_fds[SFD_SLAVE]); - do { - ok = term_raw(script_fds[SFD_USERTTY], 1); - } while (!ok && errno == EINTR); - if (!ok) - log_error(USE_ERRNO, "Can't set terminal to raw mode"); - /* * Build a path containing the session id split into two-digit subdirs, * so ID 000001 becomes /var/log/sudo-session/00/00/01. @@ -409,6 +403,15 @@ script_execv(path, argv) parent = getpid(); /* so child can pass signals back to us */ foreground = tcgetpgrp(script_fds[SFD_USERTTY]) == parent; + /* Only set tty to raw mode if we are the foreground process. */ + if (foreground) { + do { + n = term_raw(script_fds[SFD_USERTTY], 1); + } while (!n && errno == EINTR); + if (!n) + log_error(USE_ERRNO, "Can't set terminal to raw mode"); + } + /* XXX - should also catch terminal signals and kill child */ /* @@ -501,8 +504,13 @@ script_execv(path, argv) * If we are the foreground process, just resume the child. * Otherwise, re-send the signal with the handler disabled. */ - if (tcgetpgrp(script_fds[SFD_USERTTY]) == parent) { + foreground = tcgetpgrp(script_fds[SFD_USERTTY]) == parent; + if (foreground) { suspended = 0; + /* Set tty to raw mode and tell child it is in foregound. */ + do { + n = term_raw(script_fds[SFD_USERTTY], 1); + } while (!n && errno == EINTR); kill(child, SIGUSR1); break; } @@ -519,6 +527,7 @@ script_execv(path, argv) /* Suspend self and continue child when we resume. */ sa.sa_handler = SIG_DFL; sigaction(suspended, &sa, &osa); + suspend: kill(parent, suspended); /* @@ -527,7 +536,7 @@ script_execv(path, argv) */ foreground = tcgetpgrp(script_fds[SFD_USERTTY]) == parent; if (!foreground && (suspended == SIGTTOU || suspended == SIGTTIN)) - kill(parent, suspended); + goto suspend; sigaction(suspended, &osa, NULL); suspended = 0;