diff options
author | Peter Stephenson <pws@users.sourceforge.net> | 2003-03-07 12:17:49 +0000 |
---|---|---|
committer | Peter Stephenson <pws@users.sourceforge.net> | 2003-03-07 12:17:49 +0000 |
commit | a7dc5d386cb46ba7fc3fec583442d63c1cee4f75 (patch) | |
tree | e25b14241c7f62f317916b539450077d0279a08f /Src/jobs.c | |
parent | 1c300357f50b3786b3086b6d729bdef1abac7e08 (diff) | |
download | zsh-a7dc5d386cb46ba7fc3fec583442d63c1cee4f75.tar.gz zsh-a7dc5d386cb46ba7fc3fec583442d63c1cee4f75.tar.xz zsh-a7dc5d386cb46ba7fc3fec583442d63c1cee4f75.zip |
18319: Philippe Troin: fix use of process groups with su and suspend
Diffstat (limited to 'Src/jobs.c')
-rw-r--r-- | Src/jobs.c | 76 |
1 files changed, 69 insertions, 7 deletions
diff --git a/Src/jobs.c b/Src/jobs.c index fba7fd26e..359e1564e 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -30,6 +30,12 @@ #include "zsh.mdh" #include "jobs.pro" +/* the process group of the shell at startup (equal to mypgprp, except + when we started without being process group leader */ + +/**/ +mod_export pid_t origpgrp; + /* the process group of the shell */ /**/ @@ -1663,16 +1669,16 @@ bin_suspend(char *name, char **argv, Options ops, int func) signal_default(SIGTTIN); signal_default(SIGTSTP); signal_default(SIGTTOU); + + /* Move ourselves back to the process group we came from */ + release_pgrp(); } + /* suspend ourselves with a SIGTSTP */ - kill(0, SIGTSTP); + killpg(origpgrp, SIGTSTP); + if (jobbing) { - /* stay suspended */ - while (gettygrp() != mypgrp) { - sleep(1); - if (gettygrp() != mypgrp) - kill(0, SIGTTIN); - } + acquire_pgrp(); /* restore signal handling */ signal_ignore(SIGTTOU); signal_ignore(SIGTSTP); @@ -1696,3 +1702,59 @@ findjobnam(char *s) return jobnum; return -1; } + + +/* make sure we are a process group leader by creating a new process + group if necessary */ + +/**/ +void +acquire_pgrp(void) +{ + long ttpgrp; + sigset_t blockset, oldset; + + if ((mypgrp = GETPGRP()) > 0) { + sigemptyset(&blockset); + sigaddset(&blockset, SIGTTIN); + sigaddset(&blockset, SIGTTOU); + sigaddset(&blockset, SIGTSTP); + oldset = signal_block(blockset); + while ((ttpgrp = gettygrp()) != -1 && ttpgrp != mypgrp) { + mypgrp = GETPGRP(); + if (mypgrp == mypid) { + signal_setmask(oldset); + attachtty(mypgrp); /* Might generate SIGT* */ + signal_block(blockset); + } + if (mypgrp == gettygrp()) + break; + signal_setmask(oldset); + read(0, NULL, 0); /* Might generate SIGT* */ + signal_block(blockset); + mypgrp = GETPGRP(); + } + if (mypgrp != mypid) { + if (setpgrp(0, 0) == 0) { + mypgrp = mypid; + attachtty(mypgrp); + } else + opts[MONITOR] = 0; + } + signal_setmask(oldset); + } else + opts[MONITOR] = 0; +} + +/* revert back to the process group we came from (before acquire_pgrp) */ + +/**/ +void +release_pgrp(void) +{ + if (origpgrp != mypgrp) { + attachtty(origpgrp); + setpgrp(0, origpgrp); + mypgrp = origpgrp; + } +} |