From cb468501c91edfec060cd0e771e5173762feb5e4 Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Fri, 22 Aug 2014 09:12:23 -0700 Subject: 33042: $? and $pipestatus report 128+signal number for stopped jobs --- ChangeLog | 5 +++++ NEWS | 7 +++++++ Src/jobs.c | 15 ++++++++++----- 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 + + * 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 * 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. -- cgit 1.4.1