diff options
-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | Src/exec.c | 11 | ||||
-rw-r--r-- | Test/E01options.ztst | 10 |
3 files changed, 23 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog index 71f51a966..363a8324e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2007-05-23 Peter Stephenson <pws@csr.com> + * John Buddery: 23461 plus comment and test: fix race + setting up multios by blocking SIGCHLD. + * 23460: Src/exec.c, Src/jobs.c, Test/E01options.ztst: fix longstanding problem with multios attached to a subshell process. diff --git a/Src/exec.c b/Src/exec.c index 5aa3dba12..f711f3d30 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -1549,20 +1549,29 @@ closemn(struct multio **mfds, int fd) pid_t pid; struct timeval bgtime; + /* + * We need to block SIGCHLD in case the process + * we are spawning terminates before the job table + * is set up to handle it. + */ + child_block(); if ((pid = zfork(&bgtime))) { for (i = 0; i < mn->ct; i++) zclose(mn->fds[i]); zclose(mn->pipe); - if (pid == -1) { + if (pid == -1) { mfds[fd] = NULL; + child_unblock(); return; } mn->ct = 1; mn->fds[0] = fd; addproc(pid, NULL, 1, &bgtime); + child_unblock(); return; } /* pid == 0 */ + child_unblock(); closeallelse(mn); if (mn->rflag) { /* tee process */ diff --git a/Test/E01options.ztst b/Test/E01options.ztst index 0ce82b3ab..5bbf1b590 100644 --- a/Test/E01options.ztst +++ b/Test/E01options.ztst @@ -667,6 +667,16 @@ >hello >hello +# This tests for another race in multios. + print 'This test hangs the shell when it fails...' >&8 + setopt multios + echo These are the contents of the file >multio_race.out + multio_race_fn() { cat; } + multio_race_fn <$(echo multio_race.out multio_race.out) +0:Fix for race with input multios +>These are the contents of the file +>These are the contents of the file + # tried this with other things, but not on its own, so much. unsetopt nomatch print with nonomatch: flooble* |