From ff42a866e9e0a51ac01cb29ef8a3b6f6cefbb3d3 Mon Sep 17 00:00:00 2001 From: tg Date: Thu, 2 May 2013 20:28:15 +0000 Subject: [PATCH] implement set -o pipefail --- check.t | 24 +++++++++++++++++++++++- jobs.c | 7 +++++-- mksh.1 | 9 +++++++-- sh_flags.h | 5 ++++- 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/check.t b/check.t index 3434b35..1cfed7c 100644 --- a/check.t +++ b/check.t @@ -1,4 +1,4 @@ -# $MirOS: src/bin/mksh/check.t,v 1.610 2013/05/02 20:21:38 tg Exp $ +# $MirOS: src/bin/mksh/check.t,v 1.611 2013/05/02 20:28:10 tg Exp $ # $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $ # $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $ # $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $ @@ -6294,6 +6294,28 @@ expected-stdout: PIPESTATUS[0]=0 8 PIPESTATUS[0]=0 PIPESTATUS[1]=0 . --- +name: pipeline-4 +description: + Check that "set -o pipefail" does what it's supposed to +stdin: + echo 1 "$("$__progname" -c '(exit 12) | (exit 23) | (exit 42); echo $?')" . + echo 2 "$("$__progname" -c '! (exit 12) | (exit 23) | (exit 42); echo $?')" . + echo 3 "$("$__progname" -o pipefail -c '(exit 12) | (exit 23) | (exit 42); echo $?')" . + echo 4 "$("$__progname" -o pipefail -c '! (exit 12) | (exit 23) | (exit 42); echo $?')" . + echo 5 "$("$__progname" -c '(exit 23) | (exit 42) | :; echo $?')" . + echo 6 "$("$__progname" -c '! (exit 23) | (exit 42) | :; echo $?')" . + echo 7 "$("$__progname" -o pipefail -c '(exit 23) | (exit 42) | :; echo $?')" . + echo 8 "$("$__progname" -o pipefail -c '! (exit 23) | (exit 42) | :; echo $?')" . +expected-stdout: + 1 42 . + 2 0 . + 3 42 . + 4 0 . + 5 0 . + 6 1 . + 7 42 . + 8 0 . +--- name: persist-history-1 description: Check if persistent history saving works diff --git a/jobs.c b/jobs.c index 4c8b7df..dc35a33 100644 --- a/jobs.c +++ b/jobs.c @@ -1,7 +1,8 @@ /* $OpenBSD: jobs.c,v 1.38 2009/12/12 04:28:44 deraadt Exp $ */ /*- - * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 + * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011, + * 2012, 2013 * Thorsten Glaser * * Provided that these terms and disclaimer and all copyright notices @@ -22,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.95 2013/04/01 02:37:50 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.96 2013/05/02 20:28:12 tg Exp $"); #if HAVE_KILLPG #define mksh_killpg killpg @@ -1220,6 +1221,8 @@ j_waitj(Job *j, ARRAY | INT_U | AINDEX; got_array: vp->val.i = proc_errorlevel(p); + if (Flag(FPIPEFAIL) && vp->val.i) + rv = vp->val.i; p = p->next; } } diff --git a/mksh.1 b/mksh.1 index de1edec..8df2ee3 100644 --- a/mksh.1 +++ b/mksh.1 @@ -1,4 +1,4 @@ -.\" $MirOS: src/bin/mksh/mksh.1,v 1.313 2013/05/02 15:33:30 tg Exp $ +.\" $MirOS: src/bin/mksh/mksh.1,v 1.314 2013/05/02 20:28:13 tg Exp $ .\" $OpenBSD: ksh.1,v 1.146 2013/03/18 11:10:52 mpi Exp $ .\"- .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, @@ -514,7 +514,9 @@ token to form pipelines, in which the standard output of each command but the last is piped (see .Xr pipe 2 ) to the standard input of the following command. -The exit status of a pipeline is that of its last command. +The exit status of a pipeline is that of its last command, unless the +.Ic pipefail +option is set (see there). All commands of a pipeline are executed in separate subshells; this is allowed by POSIX but differs from both variants of .At @@ -4177,6 +4179,9 @@ See the and .Ic pwd commands above for more details. +.It Fl o Ic pipefail +Make the exit status of a pipeline (before logically complementing) the +rightmost non-zero errorlevel, or zero if all commands exited with zero. .It Fl o Ic posix Enable a somewhat more .Px diff --git a/sh_flags.h b/sh_flags.h index 788f3f0..a267aed 100644 --- a/sh_flags.h +++ b/sh_flags.h @@ -1,5 +1,5 @@ #if defined(SHFLAGS_DEFNS) -__RCSID("$MirOS: src/bin/mksh/sh_flags.h,v 1.13 2013/05/02 20:21:45 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh_flags.h,v 1.14 2013/05/02 20:28:15 tg Exp $"); #define FN(sname,cname,ochar,flags) /* nothing */ #elif defined(SHFLAGS_ENUMS) #define FN(sname,cname,ochar,flags) cname, @@ -88,6 +88,9 @@ FN("nounset", FNOUNSET, 'u', OF_ANY) /* ./. don't do logical cds/pwds (non-standard) */ FN("physical", FPHYSICAL, 0, OF_ANY) +/* ./. errorlevel of a pipeline is the rightmost nonzero value */ +FN("pipefail", FPIPEFAIL, 0, OF_ANY) + /* ./. adhere more closely to POSIX even when undesirable */ FN("posix", FPOSIX, 0, OF_ANY)