summaryrefslogtreecommitdiff
path: root/Src/jobs.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/jobs.c')
-rw-r--r--Src/jobs.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/Src/jobs.c b/Src/jobs.c
index 948f61b01..b47ba8c60 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,12 @@ pipecleanfilelist(LinkList filelist)
node = firstnode(filelist);
while (node) {
Jobfile jf = (Jobfile)getdata(node);
- if (jf->is_fd) {
+ if (jf->is_fd &&
+ (!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);
@@ -1379,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;
@@ -1415,9 +1427,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)
@@ -1433,7 +1445,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) &&
@@ -1473,9 +1485,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;
}
@@ -1623,7 +1635,7 @@ spawnjob(void)
deletejob(jobtab + thisjob, 0);
else {
jobtab[thisjob].stat |= STAT_LOCKED;
- pipecleanfilelist(jobtab[thisjob].filelist);
+ pipecleanfilelist(jobtab[thisjob].filelist, 0);
}
thisjob = -1;
}