summary refs log tree commit diff
path: root/Src/jobs.c
diff options
context:
space:
mode:
authorBarton E. Schaefer <schaefer@zsh.org>2014-08-22 09:12:23 -0700
committerBarton E. Schaefer <schaefer@zsh.org>2014-08-22 09:12:23 -0700
commitcb468501c91edfec060cd0e771e5173762feb5e4 (patch)
tree71467513f87ec3997d8893d60f2479adff5ef47d /Src/jobs.c
parente5b504b97586d6a5c336a51ed4d0add4cc95ce51 (diff)
downloadzsh-cb468501c91edfec060cd0e771e5173762feb5e4.tar.gz
zsh-cb468501c91edfec060cd0e771e5173762feb5e4.tar.xz
zsh-cb468501c91edfec060cd0e771e5173762feb5e4.zip
33042: $? and $pipestatus report 128+signal number for stopped jobs
Diffstat (limited to 'Src/jobs.c')
-rw-r--r--Src/jobs.c15
1 files changed, 10 insertions, 5 deletions
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.