Module Name: src Committed By: kre Date: Tue Sep 4 23:16:30 UTC 2018
Modified Files: src/bin/sh: jobs.c jobs.h sh.1 Log Message: Change the way the pipefail option works. Now it is the setting of the option when a pipeline is created that controls the way the exit status of the pipeline is calculated. Previously it was the state of the option when the exit status of the pipeline was collected. This makes no difference at all for foreground pipelines (there is no way to change the option between starting and completing the pipeline) but it does for asynchronous (background) pipelines. This was always the right way to implement it - it was originally done the other way as I could not find any other shell implemented this way - they all seemed to do it our previous way, and I could not see a good reason to be the sole different shell. However, now I know that ksh93 works as we will now work, and I am told that if the option is added to the FreeBSD shell (apparently the code exists, uncommitted) it will be the same. To generate a diff of this commit: cvs rdiff -u -r1.99 -r1.100 src/bin/sh/jobs.c cvs rdiff -u -r1.21 -r1.22 src/bin/sh/jobs.h cvs rdiff -u -r1.207 -r1.208 src/bin/sh/sh.1 Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/bin/sh/jobs.c diff -u src/bin/sh/jobs.c:1.99 src/bin/sh/jobs.c:1.100 --- src/bin/sh/jobs.c:1.99 Tue Sep 4 01:09:28 2018 +++ src/bin/sh/jobs.c Tue Sep 4 23:16:30 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: jobs.c,v 1.99 2018/09/04 01:09:28 kre Exp $ */ +/* $NetBSD: jobs.c,v 1.100 2018/09/04 23:16:30 kre Exp $ */ /*- * Copyright (c) 1991, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)jobs.c 8.5 (Berkeley) 5/4/95"; #else -__RCSID("$NetBSD: jobs.c,v 1.99 2018/09/04 01:09:28 kre Exp $"); +__RCSID("$NetBSD: jobs.c,v 1.100 2018/09/04 23:16:30 kre Exp $"); #endif #endif /* not lint */ @@ -635,7 +635,7 @@ jobstatus(const struct job *jp, int raw) int status = 0; int retval; - if (pipefail && jp->nprocs) { + if ((jp->flags & JPIPEFAIL) && jp->nprocs) { int i; for (i = 0; i < jp->nprocs; i++) @@ -1068,7 +1068,7 @@ makejob(union node *node, int nprocs) INTOFF; jp->state = JOBRUNNING; jp->used = 1; - jp->flags = 0; + jp->flags = pipefail ? JPIPEFAIL : 0; jp->nprocs = 0; jp->pgrp = 0; #if JOBS @@ -1081,8 +1081,8 @@ makejob(union node *node, int nprocs) jp->ps = &jp->ps0; } INTON; - VTRACE(DBG_JOBS, ("makejob(0x%lx, %d) returns %%%d\n", - (long)node, nprocs, jp - jobtab + 1)); + VTRACE(DBG_JOBS, ("makejob(%p, %d)%s returns %%%d\n", (void *)node, + nprocs, (jp->flags&JPIPEFAIL)?" PF":"", jp - jobtab + 1)); return jp; } Index: src/bin/sh/jobs.h diff -u src/bin/sh/jobs.h:1.21 src/bin/sh/jobs.h:1.22 --- src/bin/sh/jobs.h:1.21 Sat Oct 28 06:36:17 2017 +++ src/bin/sh/jobs.h Tue Sep 4 23:16:30 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: jobs.h,v 1.21 2017/10/28 06:36:17 kre Exp $ */ +/* $NetBSD: jobs.h,v 1.22 2018/09/04 23:16:30 kre Exp $ */ /*- * Copyright (c) 1991, 1993 @@ -79,6 +79,7 @@ struct job { char flags; #define JOBCHANGED 1 /* set if status has changed */ #define JOBWANTED 2 /* set if this is a job being sought */ +#define JPIPEFAIL 4 /* set if -o pipefail when job created */ #if JOBS char jobctl; /* job running under job control */ int prev_job; /* previous job index */ Index: src/bin/sh/sh.1 diff -u src/bin/sh/sh.1:1.207 src/bin/sh/sh.1:1.208 --- src/bin/sh/sh.1:1.207 Sat Aug 25 17:35:31 2018 +++ src/bin/sh/sh.1 Tue Sep 4 23:16:30 2018 @@ -1,4 +1,4 @@ -.\" $NetBSD: sh.1,v 1.207 2018/08/25 17:35:31 kre Exp $ +.\" $NetBSD: sh.1,v 1.208 2018/09/04 23:16:30 kre Exp $ .\" Copyright (c) 1991, 1993 .\" The Regents of the University of California. All rights reserved. .\" @@ -488,7 +488,8 @@ in the section.) (Not implemented.) .It "\ \ " Em pipefail -If set, the way the exit status of a pipeline is determined +If set when a pipeline is created, +the way the exit status of the pipeline is determined is altered. See .Sx Pipelines @@ -1155,16 +1156,16 @@ The simplest case of a pipeline is a sin .Pp If the .Ic pipefail -option is set when the pipeline completes and its status is -collected, the pipeline status is the status of -the last (rightmost) command in the pipeline to exit with non-zero exit -status, or zero, if, and only if, all commands in the pipeline -exited with a status of zero. +option was set when a pipeline was started, +the pipeline status is the status of +the last (lexically last, i.e.: rightmost) command in the +pipeline to exit with non-zero exit status, or zero, if, +and only if, all commands in the pipeline exited with a status of zero. If the .Ic pipefail -option is not set, which is the default state, +option was not set, which is the default state, the pipeline status is the exit -status of the last command in the pipeline, +status of the last (rightmost) command in the pipeline, and the exit status of any other commands in the pipeline is ignored. .Pp If the reserved word