Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Option PRINT_EXIT_VALUE doesn't always work as expected



On Fri, 30 Jul 2010 15:02:04 +0200
Vincent Lefevre <vincent@xxxxxxxxxx> wrote:
> ypig% setopt PRINT_EXIT_VALUE
> ypig% false | head -n 1
> zsh: exit 1     false | 
> zsh: done       head -n 1
> ypig% echo $pipestatus
> 1 0
> ypig% false | true
> ypig% echo $pipestatus
> 1 0

This fixes that one, sort of...  The shell does special stuff if both
elements of the pipeline are run within the shell.  The special stuff
means the pipeline looks a bit different in this case, however...

% false | true
[1]    11714 exit 1     false

but it does now report the process with the non-zero status, which is
the main point.

Index: Src/jobs.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/jobs.c,v
retrieving revision 1.75
diff -p -u -r1.75 jobs.c
--- Src/jobs.c	16 Dec 2009 18:39:07 -0000	1.75
+++ Src/jobs.c	31 Jul 2010 20:50:22 -0000
@@ -837,7 +837,7 @@ printjob(Job jn, int lng, int synch)
     Process pn;
     int job, len = 9, sig, sflag = 0, llen;
     int conted = 0, lineleng = columns, skip = 0, doputnl = 0;
-    int doneprint = 0;
+    int doneprint = 0, skip_print = 0;
     FILE *fout = (synch == 2 || !shout) ? stdout : shout;
 
     if (oldjobtab != NULL)
@@ -846,16 +846,7 @@ printjob(Job jn, int lng, int synch)
 	job = jn - jobtab;
 
     if (jn->stat & STAT_NOPRINT) {
-	if (jn->stat & STAT_DONE) {
-	    deletejob(jn);
-	    if (job == curjob) {
-		curjob = prevjob;
-		prevjob = job;
-	    }
-	    if (job == prevjob)
-		setprevjob();
-	}
-	return 0;
+	skip_print = 1;
     }
 
     if (lng < 0) {
@@ -889,11 +880,26 @@ printjob(Job jn, int lng, int synch)
 		if (job == thisjob && sig == SIGTSTP)
 		    doputnl = 1;
 	    } else if (isset(PRINTEXITVALUE) && isset(SHINSTDIN) &&
-		       WEXITSTATUS(pn->status))
+		       WEXITSTATUS(pn->status)) {
 		sflag = 1;
+		skip_print = 0;
+	    }
 	}
     }
 
+    if (skip_print) {
+	if (jn->stat & STAT_DONE) {
+	    deletejob(jn);
+	    if (job == curjob) {
+		curjob = prevjob;
+		prevjob = job;
+	    }
+	    if (job == prevjob)
+		setprevjob();
+	}
+	return 0;
+    }
+
     /*
      * - Always print if called from jobs
      * - Otherwise, require MONITOR option ("jobbing") and some

-- 
Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/



Messages sorted by: Reverse Date, Date, Thread, Author