summaryrefslogtreecommitdiffhomepage
path: root/shell/ash.c
diff options
context:
space:
mode:
authorMichael Abbott <michael@araneidae.co.uk>2009-12-04 23:03:29 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2009-12-04 23:03:29 +0100
commit359da5e3be3dfb15913c4e76d0b4a27b6400adc5 (patch)
tree8eef0b4ffa53019e8300f7cf58bcf84621e2f074 /shell/ash.c
parent285ad155c4769e4a37a936826ba41e402f7d863b (diff)
ash: implement set -o pipefail (conditional on bash compat). +39 bytes
Signed-off-by: Michael Abbott <michael@araneidae.co.uk> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell/ash.c')
-rw-r--r--shell/ash.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 65d41cc5b..e7cf7975f 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