summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--NEWS7
-rw-r--r--Src/jobs.c15
3 files changed, 22 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index b66b7e2be..28ddd557a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2014-08-22 Barton E. Schaefer <schaefer@zsh.org>
+
+ * 33042: NEWS, Src/jobs.c: $? and $pipestatus report 128+signal
+ number for stopped jobs as well as terminated jobs
+
2014-08-20 Barton E. Schaefer <schaefer@zsh.org>
* Lokesh Mandvekar: 33032: Completion/Linux/Command/_docker,
diff --git a/NEWS b/NEWS
index 3a761b1e2..1f2a9daad 100644
--- a/NEWS
+++ b/NEWS
@@ -84,6 +84,13 @@ Changes since 5.0.0
longer array is trimmed whereas the :^^ operator repeats the shorter
array enough to match the longer array.
+- The value of $? when a job becomes stopped is now the signal number plus
+ 128, for compatibility with other shells. Note that different operating
+ systems use different values e.g. for SIGTSTP, so it is not possible in
+ portable scripts to detect stopped jobs by comparing to a fixed number.
+ Also, the value of $pipestatus is now updated when a job stops, not just
+ when it exits.
+
Changes between 4.2 and 5.0.0
-----------------------------
diff --git a/Src/jobs.c b/Src/jobs.c
index c4a0707d4..83a4d96a4 100644
--- a/Src/jobs.c
+++ b/Src/jobs.c
@@ -384,9 +384,11 @@ storepipestats(Job jn, int inforeground, int fixlastval)
Process p;
for (p = jn->procs, i = 0; p && i < MAX_PIPESTATS; p = p->next, i++) {
- jpipestats[i] = ((WIFSIGNALED(p->status)) ?
+ jpipestats[i] = (WIFSIGNALED(p->status) ?
0200 | WTERMSIG(p->status) :
- WEXITSTATUS(p->status));
+ (WIFSTOPPED(p->status) ?
+ 0200 | WEXITSTATUS(p->status) :
+ WEXITSTATUS(p->status)));
if (jpipestats[i])
pipefail = jpipestats[i];
}
@@ -436,8 +438,11 @@ update_job(Job jn)
if (WIFSTOPPED(pn->status)) /* some processes are stopped */
somestopped = 1; /* so job is not done, but entry needs updating */
if (!pn->next) /* last job in pipeline determines exit status */
- val = (WIFSIGNALED(pn->status)) ? 0200 | WTERMSIG(pn->status) :
- WEXITSTATUS(pn->status);
+ val = (WIFSIGNALED(pn->status) ?
+ 0200 | WTERMSIG(pn->status) :
+ (WIFSTOPPED(pn->status) ?
+ 0200 | WEXITSTATUS(pn->status) :
+ WEXITSTATUS(pn->status)));
if (pn->pid == jn->gleader) /* if this process is process group leader */
status = pn->status;
}
@@ -537,7 +542,7 @@ update_job(Job jn)
return;
jn->stat |= (somestopped) ? STAT_CHANGED | STAT_STOPPED :
STAT_CHANGED | STAT_DONE;
- if (jn->stat & STAT_DONE) {
+ if (jn->stat & (STAT_DONE|STAT_STOPPED)) {
/* This may be redundant with printjob() but note that inforeground
* is true here for STAT_CURSH jobs even when job != thisjob, most
* likely because thisjob = -1 from exec.c:execsimple() trickery.