1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-11-27 15:01:00 +01:00

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.
This commit is contained in:
Peter Stephenson 2016-09-15 11:42:28 +01:00
parent d523ddaba2
commit 01ae64c0d7
4 changed files with 38 additions and 4 deletions

View file

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