From cda21a28e6998bb3e6170a8f496b7563c8483ec6 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Fri, 19 Jul 2013 12:09:32 +0100 Subject: 31536 with additions: Fix hang in previous process substitution fix. Close applicable file descriptors when waiting for a job. --- ChangeLog | 7 +++++++ Src/jobs.c | 25 +++++++++++++++++++++++++ Test/D03procsubst.ztst | 8 ++++++++ 3 files changed, 40 insertions(+) diff --git a/ChangeLog b/ChangeLog index 8d7e62a1b..e5777bc52 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2013-07-19 Peter Stephenson + + * 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 * 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 -- cgit 1.4.1