mirror of git://git.code.sf.net/p/zsh/code
42630: Improve process group handling in pipelines.
If process group leader exits, allow a newly forked process to become process leader. If a foreground job, reattach the shell to the terminal until that happens. Unblock signals when reading output for command subsitution so that we can do this reattaching immediately.
This commit is contained in:
parent
181f5cfabe
commit
3c74891fcd
|
@ -1,5 +1,10 @@
|
|||
2018-04-17 Peter Stephenson <p.stephenson@samsung.com>
|
||||
|
||||
* 42630: Src/exec.c, Src/signals.c: Improve process group
|
||||
handling in pipelines. Main shell will reclaim terminal if
|
||||
leader exits. Allow SIGCHLD to interrupt reading data from
|
||||
command substitution.
|
||||
|
||||
* unposted: Config/version.mk: update to 5.5.1-dev-0.
|
||||
|
||||
2018-04-16 Peter Stephenson <p.w.stephenson@ntlworld.com>
|
||||
|
|
17
Src/exec.c
17
Src/exec.c
|
@ -4576,10 +4576,20 @@ readoutput(int in, int qt, int *readerror)
|
|||
char *buf, *ptr;
|
||||
int bsiz, c, cnt = 0;
|
||||
FILE *fin;
|
||||
int q = queue_signal_level();
|
||||
|
||||
fin = fdopen(in, "r");
|
||||
ret = newlinklist();
|
||||
ptr = buf = (char *) hcalloc(bsiz = 64);
|
||||
/*
|
||||
* We need to be sensitive to SIGCHLD else we can be
|
||||
* stuck forever with important processes unreaped.
|
||||
* The case that triggered this was where the exiting
|
||||
* process is group leader of the foreground process and we need
|
||||
* to reclaim the terminal else ^C doesn't work.
|
||||
*/
|
||||
dont_queue_signals();
|
||||
child_unblock();
|
||||
while ((c = fgetc(fin)) != EOF || errno == EINTR) {
|
||||
if (c == EOF) {
|
||||
errno = 0;
|
||||
|
@ -4592,13 +4602,18 @@ readoutput(int in, int qt, int *readerror)
|
|||
cnt++;
|
||||
}
|
||||
if (++cnt >= bsiz) {
|
||||
char *pp = (char *) hcalloc(bsiz *= 2);
|
||||
char *pp;
|
||||
queue_signals();
|
||||
pp = (char *) hcalloc(bsiz *= 2);
|
||||
dont_queue_signals();
|
||||
|
||||
memcpy(pp, buf, cnt - 1);
|
||||
ptr = (buf = pp) + cnt - 1;
|
||||
}
|
||||
*ptr++ = c;
|
||||
}
|
||||
child_block();
|
||||
restore_queue_signals(q);
|
||||
if (readerror)
|
||||
*readerror = ferror(fin) ? errno : 0;
|
||||
fclose(fin);
|
||||
|
|
|
@ -537,6 +537,19 @@ wait_for_processes(void)
|
|||
#else
|
||||
update_process(pn, status);
|
||||
#endif
|
||||
if (pn->pid == jn->gleader) {
|
||||
jn->gleader = 0;
|
||||
if (!(jn->stat & STAT_NOSTTY)) {
|
||||
/*
|
||||
* This PID was in control of the terminal;
|
||||
* reclaim terminal now it has exited.
|
||||
* It's still possible some future forked
|
||||
* process of this job will become group
|
||||
* leader, however.
|
||||
*/
|
||||
attachtty(mypgrp);
|
||||
}
|
||||
}
|
||||
}
|
||||
update_job(jn);
|
||||
} else if (findproc(pid, &jn, &pn, 1)) {
|
||||
|
|
Loading…
Reference in New Issue