1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2024-05-27 18:36:05 +02:00

18319: Philippe Troin: fix use of process groups with su and suspend

This commit is contained in:
Peter Stephenson 2003-03-07 12:17:49 +00:00
parent 1c300357f5
commit a7dc5d386c
4 changed files with 92 additions and 49 deletions

View File

@ -1,3 +1,10 @@
2003-03-07 Peter Stephenson <pws@csr.com>
* 18319: Philippe Troin: Src/exec.c, Src/init.c, Src/jobs.c:
Fix various process group problems associated with certain
versions of `su'. In particular, this improves `suspend'
behaviour.
2003-03-06 Doug Kearns <djkea2@mugca.its.monash.edu.au>
* 18314: Completion/Unix/Command/_ruby: allow -I, -r, -e and script

View File

@ -1149,7 +1149,7 @@ execpline(Estate state, wordcode slcode, int how, int last1)
}
else {
close(synch[0]);
entersubsh(Z_ASYNC, 0, 0);
entersubsh(Z_ASYNC, 0, 0, 0);
if (jobtab[list_pipe_job].procs) {
if (setpgrp(0L, mypgrp = jobtab[list_pipe_job].gleader)
== -1) {
@ -1258,7 +1258,7 @@ execpline2(Estate state, wordcode pcode,
} else {
zclose(pipes[0]);
close(synch[0]);
entersubsh(how, 2, 0);
entersubsh(how, 2, 0, 0);
close(synch[1]);
execcmd(state, input, pipes[1], how, 0);
_exit(lastval);
@ -2060,7 +2060,7 @@ execcmd(Estate state, int input, int output, int how, int last1)
}
/* pid == 0 */
close(synch[0]);
entersubsh(how, (type != WC_SUBSH) && !(how & Z_ASYNC) ? 2 : 1, 0);
entersubsh(how, (type != WC_SUBSH) && !(how & Z_ASYNC) ? 2 : 1, 0, 0);
close(synch[1]);
forked = 1;
if (sigtrapped[SIGINT] & ZSIG_IGNORED)
@ -2277,7 +2277,9 @@ execcmd(Estate state, int input, int output, int how, int last1)
* exit) in case there is an error return.
*/
if (is_exec)
entersubsh(how, (type != WC_SUBSH) ? 2 : 1, 1);
entersubsh(how, (type != WC_SUBSH) ? 2 : 1, 1,
(do_exec || (type >= WC_CURSH && last1 == 1))
&& !forked);
if (type >= WC_CURSH) {
if (last1 == 1)
do_exec = 1;
@ -2536,7 +2538,7 @@ forklevel;
/**/
static void
entersubsh(int how, int cl, int fake)
entersubsh(int how, int cl, int fake, int revertpgrp)
{
int sig, monitor;
@ -2580,6 +2582,8 @@ entersubsh(int how, int cl, int fake)
}
if (!fake)
subsh = 1;
if (revertpgrp && getpid() == mypgrp)
release_pgrp();
if (SHTTY != -1) {
shout = NULL;
zclose(SHTTY);
@ -2769,7 +2773,7 @@ getoutput(char *cmd, int qt)
zclose(pipes[0]);
redup(pipes[1], 1);
opts[MONITOR] = 0;
entersubsh(Z_SYNC, 1, 0);
entersubsh(Z_SYNC, 1, 0, 0);
cmdpush(CS_CMDSUBST);
execode(prog, 0, 1);
cmdpop();
@ -2900,7 +2904,7 @@ getoutputfile(char *cmd)
/* pid == 0 */
redup(fd, 1);
opts[MONITOR] = 0;
entersubsh(Z_SYNC, 1, 0);
entersubsh(Z_SYNC, 1, 0, 0);
cmdpush(CS_CMDSUBST);
execode(prog, 0, 1);
cmdpop();
@ -2980,10 +2984,10 @@ getproc(char *cmd)
zerr("can't open %s: %e", pnam, errno);
_exit(1);
}
entersubsh(Z_ASYNC, 1, 0);
entersubsh(Z_ASYNC, 1, 0, 0);
redup(fd, out);
#else
entersubsh(Z_ASYNC, 1, 0);
entersubsh(Z_ASYNC, 1, 0, 0);
redup(pipes[out], out);
closem(0); /* this closes pipes[!out] as well */
#endif
@ -3012,7 +3016,7 @@ getpipe(char *cmd)
zclose(pipes[out]);
return pipes[!out];
}
entersubsh(Z_ASYNC, 1, 0);
entersubsh(Z_ASYNC, 1, 0, 0);
redup(pipes[out], out);
closem(0); /* this closes pipes[!out] as well */
cmdpush(CS_CMDSUBST);

View File

@ -354,7 +354,6 @@ printhelp(void)
mod_export void
init_io(void)
{
long ttpgrp;
static char outbuf[BUFSIZ], errbuf[BUFSIZ];
#ifdef RSH_BUG_WORKAROUND
@ -462,37 +461,8 @@ init_io(void)
*/
mypid = (zlong)getpid();
if (opts[MONITOR] && interact && (SHTTY != -1)) {
if ((mypgrp = GETPGRP()) > 0) {
sigset_t blockset, oldset;
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;
origpgrp = GETPGRP();
acquire_pgrp(); /* might also clear opts[MONITOR] */
} else
opts[MONITOR] = 0;
#else

View File

@ -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;
}
}