Index: Src/exec.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/exec.c,v retrieving revision 1.48 diff -b -u -r1.48 exec.c --- Src/exec.c 18 Dec 2002 16:57:02 -0000 1.48 +++ Src/exec.c 6 Mar 2003 03:52:57 -0000 @@ -1149,7 +1149,7 @@ } 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 @@ } 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 @@ } /* 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 @@ * 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 @@ /**/ 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 @@ } if (!fake) subsh = 1; + if (revertpgrp && getpid() == mypgrp) + release_pgrp(); if (SHTTY != -1) { shout = NULL; zclose(SHTTY); @@ -2769,7 +2773,7 @@ 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 @@ /* 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 @@ 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 @@ 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); Index: Src/init.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/init.c,v retrieving revision 1.30 diff -b -u -r1.30 init.c --- Src/init.c 27 Jan 2003 16:38:09 -0000 1.30 +++ Src/init.c 6 Mar 2003 03:52:57 -0000 @@ -354,7 +354,6 @@ mod_export void init_io(void) { - long ttpgrp; static char outbuf[BUFSIZ], errbuf[BUFSIZ]; #ifdef RSH_BUG_WORKAROUND @@ -462,37 +461,8 @@ */ 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 Index: Src/jobs.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/jobs.c,v retrieving revision 1.19 diff -b -u -r1.19 jobs.c --- Src/jobs.c 21 Feb 2003 14:37:03 -0000 1.19 +++ Src/jobs.c 6 Mar 2003 03:52:58 -0000 @@ -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 @@ 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); @@ -1695,4 +1701,60 @@ jobtab[jobnum].procs->text && strpfx(s, jobtab[jobnum].procs->text)) 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; + } }