From 0a20f4e5a64106d1793dd44d2fa0113417225d0f Mon Sep 17 00:00:00 2001
From: Peter Stephenson
Date: Mon, 24 Sep 2018 21:32:40 +0100
Subject: 43535: Fixes for bg / fg handling of superjobs.
Be more consistent about marking both superjob and subjob as
running when sending SIGCONT.
Send SIGCONT to superjob / subjob combination any time it is put
in foreground, even if thought running, since subjob may invisibly
have suspended.
When waiting for superjob, wait for subjob, too.
---
ChangeLog | 8 ++++++++
Src/jobs.c | 43 +++++++++++++++++++++++++++----------------
Src/signals.c | 22 +++++++++++++++++++---
3 files changed, 54 insertions(+), 19 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 8a309c42a..c61e376e2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2018-09-24 Peter Stephenson
+
+ * 43535: Src/jobs.c, Src/signals.c: fixes for bg / fg handling
+ of superjobs. Be more consistent about marking jobs running;
+ always send SIGCONT when putting superjob / subjob combination
+ into foreground; wait for both superjob and subjob when waiting
+ for superjob.
+
2018-09-24 Daniel Shahaf
* 43493: Test/V07pcre.ztst: Have V07pcre fail if PCRE was enabled
diff --git a/Src/jobs.c b/Src/jobs.c
index 2d58319a8..c399f1d3e 100644
--- a/Src/jobs.c
+++ b/Src/jobs.c
@@ -1569,10 +1569,8 @@ zwaitjob(int job, int wait_cmd)
errflag = 0; */
- if (subsh) {
+ if (subsh)
killjb(jn, SIGCONT);
- jn->stat &= ~STAT_STOPPED;
- }
if (jn->stat & STAT_SUPERJOB)
if (handle_sub(jn - jobtab, 1))
break;
@@ -1590,6 +1588,17 @@ zwaitjob(int job, int wait_cmd)
return 0;
}
+static void waitonejob(Job jn)
+{
+ if (jn->procs || jn->auxprocs)
+ zwaitjob(jn - jobtab, 0);
+ else {
+ deletejob(jn, 0);
+ pipestats[0] = lastval;
+ numpipestats = 1;
+ }
+}
+
/* wait for running job to finish */
/**/
@@ -1599,13 +1608,10 @@ waitjobs(void)
Job jn = jobtab + thisjob;
DPUTS(thisjob == -1, "No valid job in waitjobs.");
- if (jn->procs || jn->auxprocs)
- zwaitjob(thisjob, 0);
- else {
- deletejob(jn, 0);
- pipestats[0] = lastval;
- numpipestats = 1;
- }
+ waitonejob(jn);
+ if (jn->stat & STAT_SUPERJOB)
+ waitonejob(jobtab + jn->other);
+
thisjob = -1;
}
@@ -2294,11 +2300,8 @@ bin_fg(char *name, char **argv, Options ops, int func)
Process p;
if (findproc(pid, &j, &p, 0)) {
- if (j->stat & STAT_STOPPED) {
+ if (j->stat & STAT_STOPPED)
retval = (killjb(j, SIGCONT) != 0);
- if (retval == 0)
- makerunning(j);
- }
if (retval == 0) {
/*
* returns 0 for normal exit, else signal+128
@@ -2404,9 +2407,17 @@ bin_fg(char *name, char **argv, Options ops, int func)
((!jobtab[job].procs->next ||
(jobtab[job].stat & STAT_SUBLEADER) ||
killpg(jobtab[job].gleader, 0) == -1)) &&
- jobtab[jobtab[job].other].gleader)
+ jobtab[jobtab[job].other].gleader) {
attachtty(jobtab[jobtab[job].other].gleader);
- else
+ /*
+ * In case stopped by putting in background.
+ * Usually that's visible to the user, who
+ * can restart, but with a superjob this is done
+ * behind the scenes, so do it here. Should
+ * be harmless if not needed.
+ */
+ stopped = 1;
+ } else
attachtty(jobtab[job].gleader);
}
}
diff --git a/Src/signals.c b/Src/signals.c
index 26d88abc2..f294049c2 100644
--- a/Src/signals.c
+++ b/Src/signals.c
@@ -782,7 +782,20 @@ killjb(Job jn, int sig)
if (kill(pn->pid, sig) == -1 && errno != ESRCH)
err = -1;
- return err;
+ /*
+ * The following marks both the superjob and subjob
+ * as running, as done elsewhere.
+ *
+ * It's not entirely clear to me what the right way
+ * to flag the status of a still-pausd final process,
+ * as handled above, but we should be cnsistent about
+ * this inside makerunning() rather than doing anything
+ * special here.
+ */
+ if (err != -1)
+ makerunning(jn);
+
+ return err;
}
if (killpg(jobtab[jn->other].gleader, sig) == -1 && errno != ESRCH)
err = -1;
@@ -792,8 +805,11 @@ killjb(Job jn, int sig)
return err;
}
- else
- return killpg(jn->gleader, sig);
+ else {
+ err = killpg(jn->gleader, sig);
+ if (sig == SIGCONT && err != -1)
+ makerunning(jn);
+ }
}
for (pn = jn->procs; pn; pn = pn->next) {
/*
--
cgit 1.4.1