From 52364258654418127d544d31b3c49b61019e2c7e Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Sun, 6 Oct 2013 21:35:27 +0100 Subject: users:18023: Add PIPEFAIL option --- ChangeLog | 5 +++++ Doc/Zsh/options.yo | 14 ++++++++++++++ Src/jobs.c | 13 ++++++++++--- Src/options.c | 1 + Src/zsh.h | 1 + Test/E01options.ztst | 15 +++++++++++++++ 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 + + * 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 * 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 -- cgit 1.4.1