summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog3
-rw-r--r--Src/exec.c11
-rw-r--r--Test/E01options.ztst10
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*