From 28a962f557952a6001d37f4f4f7034361d11bf89 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Thu, 23 Jul 2015 09:34:11 +0100 Subject: 35849: close fd's from process substitution after fork Leaving these hanging in parent could cause deadlock: test added. --- Src/jobs.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'Src/jobs.c') diff --git a/Src/jobs.c b/Src/jobs.c index 948f61b01..a71df6838 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -1179,7 +1179,7 @@ addfilelist(const char *name, int fd) /**/ void -pipecleanfilelist(LinkList filelist) +pipecleanfilelist(LinkList filelist, int proc_subst_only) { LinkNode node; @@ -1188,7 +1188,9 @@ pipecleanfilelist(LinkList filelist) node = firstnode(filelist); while (node) { Jobfile jf = (Jobfile)getdata(node); - if (jf->is_fd) { + if (jf->is_fd && + (!proc_subst_only || + fdtable[jf->u.fd] == FDT_PROC_SUBST)) { LinkNode next = nextnode(node); zclose(jf->u.fd); (void)remnode(filelist, node); @@ -1433,7 +1435,7 @@ zwaitjob(int job, int wait_cmd) * we can't deadlock on the fact that those still exist, so * that's not a problem. */ - pipecleanfilelist(jn->filelist); + pipecleanfilelist(jn->filelist, 0); } while (!errflag && jn->stat && !(jn->stat & STAT_DONE) && @@ -1623,7 +1625,7 @@ spawnjob(void) deletejob(jobtab + thisjob, 0); else { jobtab[thisjob].stat |= STAT_LOCKED; - pipecleanfilelist(jobtab[thisjob].filelist); + pipecleanfilelist(jobtab[thisjob].filelist, 0); } thisjob = -1; } -- cgit v1.2.3 From b0ebabdc6591f1edba6eaf233a9bb61bdfa57632 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Sun, 9 Aug 2015 00:06:57 +0900 Subject: 35929: protect FDT_PROC_SUBST by #ifdef --- ChangeLog | 4 ++++ Src/jobs.c | 7 +++++-- 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'Src/jobs.c') diff --git a/ChangeLog b/ChangeLog index 45fc04732..dc3ed2382 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2015-08-09 Jun-ichi Takimoto + + * 35929: Src/jobs.c: protect FDT_PROC_SUBST by #ifdef + 2015-08-08 Jun-ichi Takimoto * 35928: Src/utils.c, Doc/Zsh/prompt.yo: date/time format such diff --git a/Src/jobs.c b/Src/jobs.c index a71df6838..933348851 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -1189,8 +1189,11 @@ pipecleanfilelist(LinkList filelist, int proc_subst_only) while (node) { Jobfile jf = (Jobfile)getdata(node); if (jf->is_fd && - (!proc_subst_only || - fdtable[jf->u.fd] == FDT_PROC_SUBST)) { + (!proc_subst_only +#ifdef FDT_PROC_SUBST + || fdtable[jf->u.fd] == FDT_PROC_SUBST +#endif + )) { LinkNode next = nextnode(node); zclose(jf->u.fd); (void)remnode(filelist, node); -- cgit v1.2.3 From 128bf385b1e8256e412d732fa9b80ecd7c5e2c73 Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Tue, 11 Aug 2015 08:53:12 -0700 Subject: 36104: change order of child_block() and dont_queue_signals() to resolve yet another race condition --- ChangeLog | 3 +++ Src/exec.c | 2 +- Src/jobs.c | 4 ++-- 3 files changed, 6 insertions(+), 3 deletions(-) (limited to 'Src/jobs.c') diff --git a/ChangeLog b/ChangeLog index 59ed6f638..816070975 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2015-08-11 Barton E. Schaefer + * 36104: Src/exec.c, Src/jobs.c: change order of child_block() + and dont_queue_signals() to resolve yet another race condition + * 36092: Doc/Zsh/mod_zpty.yo, Src/Modules/zpty.c: return the pty master file descriptor in $REPLY for use with "zle -F" etc. diff --git a/Src/exec.c b/Src/exec.c index a635c18ed..45f1c66f0 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -1607,8 +1607,8 @@ execpline(Estate state, wordcode slcode, int how, int last1) !(jobtab[list_pipe_job].stat & STAT_STOPPED)) { int q = queue_signal_level(); child_unblock(); - dont_queue_signals(); child_block(); + dont_queue_signals(); restore_queue_signals(q); } if (list_pipe_child && diff --git a/Src/jobs.c b/Src/jobs.c index 933348851..ed647b87e 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -1420,9 +1420,9 @@ zwaitjob(int job, int wait_cmd) int q = queue_signal_level(); Job jn = jobtab + job; - dont_queue_signals(); child_block(); /* unblocked during signal_suspend() */ queue_traps(wait_cmd); + dont_queue_signals(); if (jn->procs || jn->auxprocs) { /* if any forks were done */ jn->stat |= STAT_LOCKED; if (jn->stat & STAT_CHANGED) @@ -1478,9 +1478,9 @@ zwaitjob(int job, int wait_cmd) pipestats[0] = lastval; numpipestats = 1; } + restore_queue_signals(q); unqueue_traps(); child_unblock(); - restore_queue_signals(q); return 0; } -- cgit v1.2.3 From 5d019f426af8b2a600ee03e43782c24b357d1401 Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Sat, 15 Aug 2015 10:15:30 -0700 Subject: 36180: avoid infinite job stop/continue loop on "wait PID" for a background job --- ChangeLog | 5 +++++ Src/jobs.c | 9 ++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'Src/jobs.c') diff --git a/ChangeLog b/ChangeLog index a13e05d08..2966957fb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2015-08-15 Barton E. Schaefer + + * 36180: Src/jobs.c: avoid infinite job stop/continue loop on + "wait PID" for a background job + 2015-08-15 Mikael Magnusson * Eric Cook: 36091: Completion/Unix/Command/_ncftp: search diff --git a/Src/jobs.c b/Src/jobs.c index ed647b87e..b47ba8c60 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -1384,10 +1384,17 @@ waitforpid(pid_t pid, int wait_cmd) dont_queue_signals(); child_block(); /* unblocked in signal_suspend() */ queue_traps(wait_cmd); + + /* This function should never be called with a pid that is not a + * child of the current shell. Consequently, if kill(0, pid) + * fails here with ESRCH, the child has already been reaped. In + * the loop body, we expect this to happen in signal_suspend() + * via zhandler(), after which this test terminates the loop. + */ while (!errflag && (kill(pid, 0) >= 0 || errno != ESRCH)) { if (first) first = 0; - else + else if (!wait_cmd) kill(pid, SIGCONT); last_signal = -1; -- cgit v1.2.3