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:
parent
1c300357f5
commit
a7dc5d386c
|
@ -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
|
||||
|
|
24
Src/exec.c
24
Src/exec.c
|
@ -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);
|
||||
|
|
34
Src/init.c
34
Src/init.c
|
@ -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
|
||||
|
|
76
Src/jobs.c
76
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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue