about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog16
-rw-r--r--Src/exec.c4
-rw-r--r--Test/A05execution.ztst12
3 files changed, 29 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index b47ba7848..c4760218e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,14 @@
 	* Config/version.mk: update version to 5.0.4-dev-0 so as
 	not to clash with release.
 
+2013-12-20  Barton E. Schaefer  <schaefer@zsh.org>
+
+	* 32172; Test/A05execution.ztst: regression test for 32171
+	
+	* 32171: Src/exec.c: fix leaked pipe descriptor that could
+	deadlock a pipeline from a complex shell construct or function
+	into an external command
+
 2013-12-20  Peter Stephenson  <p.w.stephenson@ntlworld.com>
 
 	* unposted: Config/version.mk, Etc/FAQ.yo, README: release 5.0.4.
@@ -36,10 +44,12 @@
 
 	* unposted: NEWS: add ZLE_PROMPT_INDENT.
 
+	* 32119: Src/Zle/zle_tricky.c: left square bracket completed in
+	command position is not part of a subscript expression
+
 	* Patrick Oscity + pws: 32114: Doc/Zsh/params.yo,
-	Src/Zle/zle_refresh.c, Src/Zle/zle_tricky.c: ZLE_RPROMPT_INDENT
-	allows you to make the right prompt flush if your terminal
-	supports it.
+	Src/Zle/zle_refresh.c: ZLE_RPROMPT_INDENT allows you to make the
+	right prompt flush if your terminal supports it.
 
 2013-12-16  Barton E. Schaefer  <schaefer@zsh.org>
 
diff --git a/Src/exec.c b/Src/exec.c
index dccdc2b0d..44800339f 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -1691,6 +1691,7 @@ execpline2(Estate state, wordcode pcode,
 	execcmd(state, input, output, how, last1 ? 1 : 2);
     else {
 	int old_list_pipe = list_pipe;
+	int subsh_close = -1;
 	Wordcode next = state->pc + (*state->pc), pc;
 	wordcode code;
 
@@ -1738,6 +1739,7 @@ execpline2(Estate state, wordcode pcode,
 	} else {
 	    /* otherwise just do the pipeline normally. */
 	    addfilelist(NULL, pipes[0]);
+	    subsh_close = pipes[0];
 	    execcmd(state, input, pipes[1], how, 0);
 	}
 	zclose(pipes[1]);
@@ -1750,6 +1752,8 @@ execpline2(Estate state, wordcode pcode,
 	execpline2(state, *state->pc++, how, pipes[0], output, last1);
 	list_pipe = old_list_pipe;
 	cmdpop();
+	if (subsh_close != pipes[0])
+	    zclose(pipes[0]);
     }
 }
 
diff --git a/Test/A05execution.ztst b/Test/A05execution.ztst
index c8320a14d..61d24fe1e 100644
--- a/Test/A05execution.ztst
+++ b/Test/A05execution.ztst
@@ -202,3 +202,15 @@ F:the bug is still there or it reappeared. See workers-29973 for details.
 0:Check $pipestatus with a known difficult case
 >1 0 1 0 0
 F:This similar test was triggering a reproducible failure with pipestatus.
+
+  { unsetopt MONITOR } 2>/dev/null
+  coproc { read -Et 5 || kill -INT $$ }
+  print -u $ZTST_fd 'This test takes 5 seconds to fail...'
+  { printf "%d\n" {1..20000} } | ( read -E )
+  print -p done
+  read -Ep
+0:Bug regression: piping a shell construct to an external process may hang
+>1
+>done
+F:This test checks for a file descriptor leak that could cause the left
+F:side of a pipe to block on write after the right side has exited