diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | Src/exec.c | 29 |
2 files changed, 33 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog index c5355ef50..ff4858d3d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-12-12 Peter Stephenson <p.w.stephenson@ntlworld.com> + + * 30000 plus a couple of comments: Src/exec.c: Better POSIXJOBS + behaviour: don't restore default behaviour for SIGTTOU etc. if + we're still doing job handling, and only continue with job + handling if this is a (...) subshell. + 2011-12-11 Peter Stephenson <p.w.stephenson@ntlworld.com> * discussed in 29984: Doc/Zsh/compsys.yo: use m+7 for files @@ -15725,5 +15732,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.5536 $ +* $Revision: 1.5537 $ ***************************************************** diff --git a/Src/exec.c b/Src/exec.c index 2c644e6b7..9b3c50372 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -896,14 +896,16 @@ enum { /* Release the process group if pid is the shell's process group */ ESUB_REVERTPGRP = 0x10, /* Don't handle the MONITOR option even if previously set */ - ESUB_NOMONITOR = 0x20 + ESUB_NOMONITOR = 0x20, + /* This is a subshell where job control is allowed */ + ESUB_JOB_CONTROL = 0x40 }; /**/ static void entersubsh(int flags) { - int sig, monitor; + int sig, monitor, job_control_ok; if (!(flags & ESUB_KEEPTRAP)) for (sig = 0; sig < VSIGCOUNT; sig++) @@ -911,6 +913,7 @@ entersubsh(int flags) sig != SIGDEBUG && sig != SIGZERR) unsettrap(sig); monitor = isset(MONITOR); + job_control_ok = monitor && (flags & ESUB_JOB_CONTROL) && isset(POSIXJOBS); if (flags & ESUB_NOMONITOR) opts[MONITOR] = 0; if (!isset(MONITOR)) { @@ -938,6 +941,16 @@ entersubsh(int flags) } else if (!jobtab[thisjob].gleader || setpgrp(0L, jobtab[thisjob].gleader) == -1) { + /* + * This is the standard point at which a newly started + * process gets put into the foreground by taking over + * the terminal. Note that in normal circumstances we do + * this only from the process itself. This only works if + * we are still ignoring SIGTTOU at this point; in this + * case ignoring the signal has the special effect that + * the operation is allowed to work (in addition to not + * causing the shell to be suspended). + */ jobtab[thisjob].gleader = getpid(); if (list_pipe_job != thisjob && !jobtab[list_pipe_job].gleader) @@ -959,7 +972,13 @@ entersubsh(int flags) if ((flags & ESUB_REVERTPGRP) && getpid() == mypgrp) release_pgrp(); shout = NULL; - if (isset(MONITOR)) { + if (!job_control_ok) { + /* + * If this process is not goign to be doing job control, + * we don't want to do special things with the corresponding + * signals. If it is, we need to keep the special behaviour: + * see note about attachtty() above. + */ signal_default(SIGTTOU); signal_default(SIGTTIN); signal_default(SIGTSTP); @@ -971,7 +990,7 @@ entersubsh(int flags) } if (!(sigtrapped[SIGQUIT] & ZSIG_IGNORED)) signal_default(SIGQUIT); - if (!isset(POSIXJOBS)) + if (!job_control_ok) opts[MONITOR] = 0; opts[USEZLE] = 0; zleactive = 0; @@ -2829,6 +2848,8 @@ execcmd(Estate state, int input, int output, int how, int last1) flags = ((how & Z_ASYNC) ? ESUB_ASYNC : 0) | ESUB_PGRP; if ((type != WC_SUBSH) && !(how & Z_ASYNC)) flags |= ESUB_KEEPTRAP; + if (type == WC_SUBSH && !(how & Z_ASYNC)) + flags |= ESUB_JOB_CONTROL; entersubsh(flags); close(synch[1]); forked = 1; |