summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJun-ichi Takimoto <takimoto-j@kba.biglobe.ne.jp>2022-06-03 19:32:56 +0900
committerJun-ichi Takimoto <takimoto-j@kba.biglobe.ne.jp>2022-06-03 19:32:56 +0900
commit22b1a91c2a07e6d6a57975a1ab47d66f92aa21f2 (patch)
tree3c6a40302e7ba513f75aa10b918793d56abcf5f6
parent8756cc6add3d27d05e869fc7317e3043ab2be5b2 (diff)
downloadzsh-22b1a91c2a07e6d6a57975a1ab47d66f92aa21f2.tar.gz
zsh-22b1a91c2a07e6d6a57975a1ab47d66f92aa21f2.zip
50306: fix wait for child that was stopped/continued
do not call addbgstatus() when child is stopped/continued
-rw-r--r--ChangeLog5
-rw-r--r--Src/jobs.c20
-rw-r--r--Src/signals.c10
-rw-r--r--Test/A05execution.ztst7
4 files changed, 34 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 43a805bc7..780f967f6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2022-06-03 Jun-ichi Takimoto <takimoto-j@kba.biglobe.ne.jp>
+
+ * 50306: Src/jobs.c, Src/signals.c, Test/A05execution.ztst: fix
+ wait builtin for child that has been stopped and continued.
+
2022-05-30 Bart Schaefer <schaefer@zsh.org>
* Marlon Richert: 50307 (cf. PWS 50205):
diff --git a/Src/jobs.c b/Src/jobs.c
index a91ef787f..aa32f4e80 100644
--- a/Src/jobs.c
+++ b/Src/jobs.c
@@ -414,7 +414,7 @@ storepipestats(Job jn, int inforeground, int fixlastval)
jpipestats[i] = (WIFSIGNALED(p->status) ?
0200 | WTERMSIG(p->status) :
(WIFSTOPPED(p->status) ?
- 0200 | WEXITSTATUS(p->status) :
+ 0200 | WSTOPSIG(p->status) :
WEXITSTATUS(p->status)));
if (jpipestats[i])
pipefail = jpipestats[i];
@@ -471,7 +471,7 @@ update_job(Job jn)
val = (WIFSIGNALED(pn->status) ?
0200 | WTERMSIG(pn->status) :
(WIFSTOPPED(pn->status) ?
- 0200 | WEXITSTATUS(pn->status) :
+ 0200 | WSTOPSIG(pn->status) :
WEXITSTATUS(pn->status)));
signalled = WIFSIGNALED(pn->status);
}
@@ -2221,6 +2221,7 @@ addbgstatus(pid_t pid, int status)
{
static long child_max;
Bgstatus bgstatus_entry;
+ LinkNode node;
if (!child_max) {
#ifdef _SC_CHILD_MAX
@@ -2244,6 +2245,21 @@ addbgstatus(pid_t pid, int status)
if (!bgstatus_list)
return;
}
+#ifdef DEBUG
+ /* See if an entry already exists for the pid */
+ for (node = firstnode(bgstatus_list); node; incnode(node)) {
+ bgstatus_entry = (Bgstatus)getdata(node);
+ if (bgstatus_entry->pid == pid) {
+ /* In theory this should not happen because addbgstatus() is
+ * called only once when the process exits or gets killed. */
+ dputs("addbgstatus called again: pid %d: status %d -> %d",
+ pid, bgstatus_entry->status, status);
+ bgstatus_entry->status = status;
+ return;
+ }
+ }
+#endif
+ /* Add an entry for the pid */
if (bgstatus_count == child_max) {
/* Overflow. List is in order, remove first */
rembgstatus(firstnode(bgstatus_list));
diff --git a/Src/signals.c b/Src/signals.c
index 5c787e2a8..a61368554 100644
--- a/Src/signals.c
+++ b/Src/signals.c
@@ -576,12 +576,10 @@ wait_for_processes(void)
*/
if (jn && !(jn->stat & (STAT_CURSH|STAT_BUILTIN)) &&
jn - jobtab != thisjob) {
- int val = (WIFSIGNALED(status) ?
- 0200 | WTERMSIG(status) :
- (WIFSTOPPED(status) ?
- 0200 | WEXITSTATUS(status) :
- WEXITSTATUS(status)));
- addbgstatus(pid, val);
+ if (WIFEXITED(status))
+ addbgstatus(pid, WEXITSTATUS(status));
+ else if (WIFSIGNALED(status))
+ addbgstatus(pid, 0200 | WTERMSIG(status));
}
unqueue_signals();
diff --git a/Test/A05execution.ztst b/Test/A05execution.ztst
index d95ee363c..b257ddf2c 100644
--- a/Test/A05execution.ztst
+++ b/Test/A05execution.ztst
@@ -396,6 +396,13 @@ F:anonymous function, and a descriptor leak when backgrounding a pipeline
# TBD: the 0 above is believed to be bogus and should also be turned
# into 127 when the ccorresponding bug is fixed in the main shell.
+ sleep 1 & pid=$!
+ kill -STOP $pid
+ sleep 1
+ kill -CONT $pid
+ wait $pid
+0:wait for stopped and continued process
+
# Without the outer subshell, the test harness reports the pre-46060 behaviour
# as "skipped" rather than "failed".
(( exit 130 ) | { sleep 1; echo hello })