about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <p.w.stephenson@ntlworld.com>2013-10-06 21:35:27 +0100
committerPeter Stephenson <p.w.stephenson@ntlworld.com>2013-10-06 21:35:27 +0100
commit52364258654418127d544d31b3c49b61019e2c7e (patch)
treec9942861227e2834769bea53a23f530703b8a8f0
parent16ff79a885f28bc9509901dd5d8ce9ccc9960811 (diff)
downloadzsh-52364258654418127d544d31b3c49b61019e2c7e.tar.gz
zsh-52364258654418127d544d31b3c49b61019e2c7e.tar.xz
zsh-52364258654418127d544d31b3c49b61019e2c7e.zip
users:18023: Add PIPEFAIL option
-rw-r--r--ChangeLog5
-rw-r--r--Doc/Zsh/options.yo14
-rw-r--r--Src/jobs.c13
-rw-r--r--Src/options.c1
-rw-r--r--Src/zsh.h1
-rw-r--r--Test/E01options.ztst15
6 files changed, 46 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 1cf815eee..2613d5189 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2013-10-06  Peter Stephenson  <p.w.stephenson@ntlworld.com>
+
+	* users/18023: Doc/Zsh/options.yo, Src/jobs.c, Src/options.c,
+	Src/zsh.h, Test/E01options.ztst: add PIPEFAIL option and test.
+
 2013-10-05  Peter Stephenson  <p.w.stephenson@ntlworld.com>
 
 	* Hang Pingtian: 31789: Src/hist.c: add history for
diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo
index ec862321e..71bddd570 100644
--- a/Doc/Zsh/options.yo
+++ b/Doc/Zsh/options.yo
@@ -1683,6 +1683,20 @@ Sequences of digits indicating a numeric base such as the `tt(08)'
 component in `tt(08#77)' are always interpreted as decimal, regardless
 of leading zeroes.
 )
+pindex(PIPE_FAIL)
+pindex(NO_PIPE_FAIL)
+pindex(PIPEFAIL)
+pindex(NOPIPEFAIL)
+cindex(exit status from pipeline)
+cindex(status, on exit from pipeline)
+cindex(pipeline, exit status from)
+itme(tt(PIPE_FAIL))(
+By default, when a pipeline exits the exit status recorded by the shell
+and returned by the shell variable tt($?) reflects that of the
+rightmost element of a pipeline.  If this option is set, the exit status
+instead reflects the status of the rightmost element of the pipeline
+that was non-zero, or zero if all elements exited with zero status.
+)
 pindex(SOURCE_TRACE)
 pindex(NO_SOURCE_TRACE)
 pindex(SOURCETRACE)
diff --git a/Src/jobs.c b/Src/jobs.c
index e1b24b2c9..b9d7a84cc 100644
--- a/Src/jobs.c
+++ b/Src/jobs.c
@@ -508,15 +508,22 @@ update_job(Job jn)
     jn->stat |= (somestopped) ? STAT_CHANGED | STAT_STOPPED :
 	STAT_CHANGED | STAT_DONE;
     if (job == thisjob && (jn->stat & STAT_DONE)) {
-	int i;
+	int i, newlastval = 0;
 	Process p;
 
-	for (p = jn->procs, i = 0; p && i < MAX_PIPESTATS; p = p->next, i++)
+	for (p = jn->procs, i = 0; p && i < MAX_PIPESTATS; p = p->next, i++) {
 	    pipestats[i] = ((WIFSIGNALED(p->status)) ?
 			    0200 | WTERMSIG(p->status) :
 			    WEXITSTATUS(p->status));
-	if ((jn->stat & STAT_CURSH) && i < MAX_PIPESTATS)
+	    if (pipestats[i])
+		newlastval = pipestats[i];
+	}
+	if ((jn->stat & STAT_CURSH) && i < MAX_PIPESTATS) {
 	    pipestats[i++] = lastval;
+	    if (!lastval && isset(PIPEFAIL))
+		lastval = newlastval;
+	} else if (isset(PIPEFAIL))
+	    lastval= newlastval;
 	numpipestats = i;
     }
     if (!inforeground &&
diff --git a/Src/options.c b/Src/options.c
index ad869b253..ce73d9901 100644
--- a/Src/options.c
+++ b/Src/options.c
@@ -205,6 +205,7 @@ static struct optname optns[] = {
 {{NULL, "overstrike",	      0},			 OVERSTRIKE},
 {{NULL, "pathdirs",	      OPT_EMULATE},		 PATHDIRS},
 {{NULL, "pathscript",	      OPT_EMULATE|OPT_BOURNE},	 PATHSCRIPT},
+{{NULL, "pipefail",           OPT_EMULATE},              PIPEFAIL},
 {{NULL, "posixaliases",       OPT_EMULATE|OPT_BOURNE},	 POSIXALIASES},
 {{NULL, "posixbuiltins",      OPT_EMULATE|OPT_BOURNE},	 POSIXBUILTINS},
 {{NULL, "posixcd",            OPT_EMULATE|OPT_BOURNE},	 POSIXCD},
diff --git a/Src/zsh.h b/Src/zsh.h
index e6f0f65db..a46898d7d 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -2121,6 +2121,7 @@ enum {
     OVERSTRIKE,
     PATHDIRS,
     PATHSCRIPT,
+    PIPEFAIL,
     POSIXALIASES,
     POSIXBUILTINS,
     POSIXCD,
diff --git a/Test/E01options.ztst b/Test/E01options.ztst
index bcb34c352..e00eb0e9c 100644
--- a/Test/E01options.ztst
+++ b/Test/E01options.ztst
@@ -1096,3 +1096,18 @@
 0:IGNORE_CLOSE_BRACES option
 >this is OK
 >6
+
+  (setopt pipefail
+  true | true | true
+  print $?
+  true | false | true
+  print $?
+  exit 2 | false | true
+  print $?
+  false | exit 2 | true
+  print $?)
+0:PIPE_FAIL option
+>0
+>1
+>1
+>2