summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@zsh.org>2013-07-19 12:09:32 +0100
committerPeter Stephenson <pws@zsh.org>2013-07-19 12:09:32 +0100
commitcda21a28e6998bb3e6170a8f496b7563c8483ec6 (patch)
treecf5f17b8a71b41ee59602a1a01c34574d1f22034
parent3c5732223f65309c6820f15b8519f674bd21185b (diff)
downloadzsh-cda21a28e6998bb3e6170a8f496b7563c8483ec6.tar.gz
zsh-cda21a28e6998bb3e6170a8f496b7563c8483ec6.zip
31536 with additions: Fix hang in previous process substitution fix.
Close applicable file descriptors when waiting for a job.
-rw-r--r--ChangeLog7
-rw-r--r--Src/jobs.c25
-rw-r--r--Test/D03procsubst.ztst8
3 files changed, 40 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 8d7e62a1b..e5777bc52 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2013-07-19 Peter Stephenson <p.stephenson@samsung.com>
+
+ * 31536 (plus memory leak fixed, plus test code):
+ Src/jobs.c, Test/D03procsubst.ztst: fix hang in 31528 by
+ closing process substitution file descriptors when waiting
+ for job to finish.
+
2013-07-17 Peter Stephenson <p.w.stephenson@ntlworld.com>
* 31528: Src/exec.c, Src/jobs.c, Src/zsh.h: use job table
diff --git a/Src/jobs.c b/Src/jobs.c
index a1955bb0f..e1b24b2c9 100644
--- a/Src/jobs.c
+++ b/Src/jobs.c
@@ -1368,6 +1368,31 @@ zwaitjob(int job, int wait_cmd)
jn->stat |= STAT_LOCKED;
if (jn->stat & STAT_CHANGED)
printjob(jn, !!isset(LONGLISTJOBS), 1);
+ if (jn->filelist) {
+ /*
+ * The main shell is finished with any file descriptors used
+ * for process substitution associated with this job: close
+ * them to indicate to listeners there's no more input.
+ *
+ * Note we can't safely delete temporary files yet as these
+ * are directly visible to other processes. However,
+ * we can't deadlock on the fact that those still exist, so
+ * that's not a problem.
+ */
+ LinkNode node = firstnode(jn->filelist);
+ while (node) {
+ Jobfile jf = (Jobfile)getdata(node);
+ if (jf->is_fd) {
+ LinkNode next = nextnode(node);
+ (void)remnode(jn->filelist, node);
+ zclose(jf->u.fd);
+ zfree(jf, sizeof(*jf));
+ node = next;
+ } else {
+ incnode(node);
+ }
+ }
+ }
while (!errflag && jn->stat &&
!(jn->stat & STAT_DONE) &&
!(interact && (jn->stat & STAT_STOPPED))) {
diff --git a/Test/D03procsubst.ztst b/Test/D03procsubst.ztst
index 88fa902bb..c763f6e0f 100644
--- a/Test/D03procsubst.ztst
+++ b/Test/D03procsubst.ztst
@@ -107,3 +107,11 @@
>third: This becomes argument three
>fourth: and this argument four
+ () {
+ # Make sure we don't close the file descriptor too early
+ eval 'print "Execute a complicated command first" | sed s/command/order/'
+ cat $1
+ } <(echo This line was brought to you by the letters F and D)
+0:Process substitution as anonymous function argument
+>Execute a complicated order first
+>This line was brought to you by the letters F and D