[git commit master] ash: implement set -o pipefail (conditional on bash compat). +39 bytes

Denys Vlasenko vda.linux at googlemail.com
Fri Dec 4 22:03:29 UTC 2009


commit: http://git.busybox.net/busybox/commit/?id=359da5e3be3dfb15913c4e76d0b4a27b6400adc5
branch: http://git.busybox.net/busybox/commit/?id=refs/heads/master

Signed-off-by: Michael Abbott <michael at araneidae.co.uk>
Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 shell/ash.c |   24 +++++++++++++++++++++---
 1 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/shell/ash.c b/shell/ash.c
index 65d41cc..e7cf797 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -101,6 +101,9 @@ static const char *const optletters_optnames[] = {
 	"b"   "notify",
 	"u"   "nounset",
 	"\0"  "vi",
+#if ENABLE_ASH_BASH_COMPAT
+	"\0"  "pipefail"
+#endif
 #if DEBUG
 	,"\0"  "nolog"
 	,"\0"  "debug"
@@ -178,9 +181,14 @@ struct globals_misc {
 #define bflag optlist[11]
 #define uflag optlist[12]
 #define viflag optlist[13]
+#if ENABLE_ASH_BASH_COMPAT
+# define pipefail optlist[14]
+#else
+# define pipefail 0
+#endif
 #if DEBUG
-#define nolog optlist[14]
-#define debug optlist[15]
+# define nolog optlist[14 + ENABLE_ASH_BASH_COMPAT]
+# define debug optlist[15 + ENABLE_ASH_BASH_COMPAT]
 #endif
 
 	/* trap handler commands */
@@ -3999,13 +4007,23 @@ jobscmd(int argc UNUSED_PARAM, char **argv)
 }
 #endif /* JOBS */
 
+/* Called only on finished or stopped jobs (no members are running) */
 static int
 getstatus(struct job *job)
 {
 	int status;
 	int retval;
+	struct procstat *ps;
+
+	/* Fetch last member's status */
+	ps = job->ps + job->nprocs - 1;
+	status = ps->ps_status;
+	if (pipefail) {
+		/* "set -o pipefail" mode: use last _nonzero_ status */
+		while (status == 0 && --ps >= job->ps)
+			status = ps->ps_status;
+	}
 
-	status = job->ps[job->nprocs - 1].ps_status;
 	retval = WEXITSTATUS(status);
 	if (!WIFEXITED(status)) {
 #if JOBS
-- 
1.6.3.3



More information about the busybox-cvs mailing list