diff options
author | Peter Stephenson <p.w.stephenson@ntlworld.com> | 2016-09-16 21:55:55 +0100 |
---|---|---|
committer | Peter Stephenson <p.w.stephenson@ntlworld.com> | 2016-09-16 21:55:55 +0100 |
commit | c355a5f41f4cd0fd3892aa8815aab08ac0a2f921 (patch) | |
tree | 827dad42831c8fb87b0d6c6f0e416046f1a1310f /Src | |
parent | 327f3dd3adfc8fdd6c356722d093a340b81190a7 (diff) | |
download | zsh-c355a5f41f4cd0fd3892aa8815aab08ac0a2f921.tar.gz zsh-c355a5f41f4cd0fd3892aa8815aab08ac0a2f921.tar.xz zsh-c355a5f41f4cd0fd3892aa8815aab08ac0a2f921.zip |
39362: another race with pipeline handling.
When forking the shell to control the right hand side, the forked subshell now always starts its own process group, to avoid getting a spurious additional SIGSTOP.
Diffstat (limited to 'Src')
-rw-r--r-- | Src/exec.c | 34 |
1 files changed, 9 insertions, 25 deletions
diff --git a/Src/exec.c b/Src/exec.c index 0755d55cd..9a7234e5f 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -1710,39 +1710,23 @@ execpline(Estate state, wordcode slcode, int how, int last1) break; } else { - Job pjn = jobtab + list_pipe_job; close(synch[0]); entersubsh(ESUB_ASYNC); /* * At this point, we used to attach this process * to the process group of list_pipe_job (the * new superjob) any time that was still available. - * That caused problems when the fork happened - * early enough that the subjob is in that - * process group, since then we will stop this - * job when we signal the subjob, and we have - * no way here to know that we shouldn't also - * send STOP to itself, resulting in two stops. - * So don't do that if the original - * list_pipe_job has exited. + * That caused problems in at least two + * cases because this forked shell was then + * suspended with the right hand side of the + * pipeline, and the SIGSTOP below suspended + * it a second time when it was continued. * - * The choice here needs to match the assumption - * made when handling SUBLEADER above that the - * process group is our own PID. I'm not sure - * if there's a potential race for that. But - * setting up a new process group if the - * superjob is still functioning seems the wrong - * thing to do. + * It's therefore not clear entirely why you'd ever + * do anything other than the following, but no + * doubt we'll find out... */ - if (pjn->procs && - (pjn->stat & STAT_INUSE) && - !(pjn->stat & STAT_DONE)) { - if (setpgrp(0L, mypgrp = jobtab[list_pipe_job].gleader) - == -1) { - setpgrp(0L, mypgrp = getpid()); - } - } else - setpgrp(0L, mypgrp = getpid()); + setpgrp(0L, mypgrp = getpid()); close(synch[1]); kill(getpid(), SIGSTOP); list_pipe = 0; |