diff options
author | Peter Stephenson <pws@zsh.org> | 2016-09-15 11:42:28 +0100 |
---|---|---|
committer | Peter Stephenson <pws@zsh.org> | 2016-09-16 09:39:33 +0100 |
commit | 01ae64c0d74c17e36bfe6f52394a59754b8e8c92 (patch) | |
tree | 5c76926c158e8ef5460b86b1c5abc7dbc61a9151 /Src/exec.c | |
parent | d523ddaba2cd160343b54d3e38ea001c63a87dc6 (diff) | |
download | zsh-01ae64c0d74c17e36bfe6f52394a59754b8e8c92.tar.gz zsh-01ae64c0d74c17e36bfe6f52394a59754b8e8c92.tar.xz zsh-01ae64c0d74c17e36bfe6f52394a59754b8e8c92.zip |
39331: Reparent subjob on fork with exited superjob.
Fixes case of v() { { vim - } always { true } } ls | v ^Z fg Tentative fix: still a race at exit where zsh forked by ^Z is stopped when restarted.
Diffstat (limited to 'Src/exec.c')
-rw-r--r-- | Src/exec.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/Src/exec.c b/Src/exec.c index cfd633add..21270c82d 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -1570,6 +1570,7 @@ execpline(Estate state, wordcode slcode, int how, int last1) if (nowait) { if(!pline_level) { + int jobsub; struct process *pn, *qn; curjob = newjob; @@ -1582,6 +1583,20 @@ execpline(Estate state, wordcode slcode, int how, int last1) if (!jn->procs->next || lpforked == 2) { jn->gleader = list_pipe_pid; jn->stat |= STAT_SUBLEADER; + /* + * Pick up any subjob that's still lying around + * as it's now our responsibility. + * If we find it we're a SUPERJOB. + */ + for (jobsub = 1; jobsub <= maxjob; jobsub++) { + Job jnsub = jobtab + jobsub; + if (jnsub->stat & STAT_SUBJOB_ORPHANED) { + jn->other = jobsub; + jn->stat |= STAT_SUPERJOB; + jnsub->stat &= ~STAT_SUBJOB_ORPHANED; + jnsub->other = list_pipe_pid; + } + } } for (pn = jobtab[jn->other].procs; pn; pn = pn->next) if (WIFSTOPPED(pn->status)) @@ -1593,7 +1608,8 @@ execpline(Estate state, wordcode slcode, int how, int last1) } jn->stat &= ~(STAT_DONE | STAT_NOPRINT); - jn->stat |= STAT_STOPPED | STAT_CHANGED | STAT_LOCKED; + jn->stat |= STAT_STOPPED | STAT_CHANGED | STAT_LOCKED | + STAT_INUSE; printjob(jn, !!isset(LONGLISTJOBS), 1); } else if (newjob != list_pipe_job) @@ -1669,6 +1685,7 @@ execpline(Estate state, wordcode slcode, int how, int last1) jobtab[list_pipe_job].stat |= STAT_SUPERJOB; jn->stat |= STAT_SUBJOB | STAT_NOPRINT; jn->other = pid; + jn->gleader = jobtab[list_pipe_job].gleader; } if ((list_pipe || last1) && hasprocs(list_pipe_job)) killpg(jobtab[list_pipe_job].gleader, SIGSTOP); |