diff options
author | brian <brian@FreeBSD.org> | 2006-01-03 09:17:04 +0000 |
---|---|---|
committer | brian <brian@FreeBSD.org> | 2006-01-03 09:17:04 +0000 |
commit | 75107ac807800d6b2d84af45093d4e3572f35e57 (patch) | |
tree | b9de1769e78798f54b3110532e1397d41b79ab71 /usr.bin | |
parent | d2cea5305fb9934620b0b2ddaccb11e6d59f8462 (diff) | |
download | FreeBSD-src-75107ac807800d6b2d84af45093d4e3572f35e57.zip FreeBSD-src-75107ac807800d6b2d84af45093d4e3572f35e57.tar.gz |
Fix the other su bug reintroduced two commits ago, namely
$ su
% kill -STOP $$
where su is executing (t)csh. csh's job handling is a little more
special than that of (a)sh, bash and even zsh and blows up a little
more spectacularly. This modification restores the original mucking
about with the tty pgrp, but is careful to only do it when su (or
su's child) is the foreground process.
While I'm here, fix a STDERR_FILENO spelling as suggested by bde.
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/su/su.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/usr.bin/su/su.c b/usr.bin/su/su.c index ba592b0..dd1602d 100644 --- a/usr.bin/su/su.c +++ b/usr.bin/su/su.c @@ -156,7 +156,7 @@ main(int argc, char *argv[]) char * const *b; } np; uid_t ruid; - pid_t child_pid, pid; + pid_t child_pid, child_pgrp, pid; int asme, ch, asthem, fastlogin, prio, i, retcode, statusp, setmaclabel; u_int setwhat; @@ -392,17 +392,30 @@ main(int argc, char *argv[]) sa.sa_handler = SIG_IGN; sigaction(SIGTTOU, &sa, NULL); close(fds[0]); + setpgid(child_pid, child_pid); + if (tcgetpgrp(STDERR_FILENO) == getpgrp()) + tcsetpgrp(STDERR_FILENO, child_pid); close(fds[1]); sigaction(SIGPIPE, &sa_pipe, NULL); while ((pid = waitpid(child_pid, &statusp, WUNTRACED)) != -1) { if (WIFSTOPPED(statusp)) { + child_pgrp = getpgid(child_pid); + if (tcgetpgrp(STDERR_FILENO) == child_pgrp) + tcsetpgrp(STDERR_FILENO, getpgrp()); kill(getpid(), SIGSTOP); + if (tcgetpgrp(STDERR_FILENO) == getpgrp()) { + child_pgrp = getpgid(child_pid); + tcsetpgrp(STDERR_FILENO, child_pgrp); + } kill(child_pid, SIGCONT); statusp = 1; continue; } break; } + child_pgrp = getpgid(child_pid); + if (tcgetpgrp(STDERR_FILENO) == child_pgrp) + tcsetpgrp(STDERR_FILENO, getpgrp()); if (pid == -1) err(1, "waitpid"); PAM_END(); |