View | Details | Raw Unified | Return to bug 224270 | Differences between
and this patch

Collapse All | Expand All

(-)b/bin/sh/jobs.c (-3 / +20 lines)
Lines 104-109 struct job { Link Here
104
	char changed;		/* true if status has changed */
104
	char changed;		/* true if status has changed */
105
	char foreground;	/* true if running in the foreground */
105
	char foreground;	/* true if running in the foreground */
106
	char remembered;	/* true if $! referenced */
106
	char remembered;	/* true if $! referenced */
107
	char pipefail;		/* pass any non-zero status */
107
#if JOBS
108
#if JOBS
108
	char jobctl;		/* job running under job control */
109
	char jobctl;		/* job running under job control */
109
	struct job *next;	/* job used after this one */
110
	struct job *next;	/* job used after this one */
Lines 143-148 static void setcurjob(struct job *); Link Here
143
static void deljob(struct job *);
144
static void deljob(struct job *);
144
static struct job *getcurjob(struct job *);
145
static struct job *getcurjob(struct job *);
145
#endif
146
#endif
147
static int getjobstatus(const struct job *);
146
static void printjobcmd(struct job *);
148
static void printjobcmd(struct job *);
147
static void showjob(struct job *, int);
149
static void showjob(struct job *, int);
148
150
Lines 340-345 jobscmd(int argc __unused, char *argv[] __unused) Link Here
340
	return (0);
342
	return (0);
341
}
343
}
342
344
345
static int getjobstatus(const struct job *jp)
346
{
347
	int i, status;
348
349
	if (!jp->pipefail)
350
		return (jp->ps[jp->nprocs - 1].status);
351
	for (i = jp->nprocs - 1; i >= 0; i--) {
352
		status = jp->ps[i].status;
353
		if (status != 0)
354
			return (status);
355
	}
356
	return (0);
357
}
358
343
static void
359
static void
344
printjobcmd(struct job *jp)
360
printjobcmd(struct job *jp)
345
{
361
{
Lines 376-382 showjob(struct job *jp, int mode) Link Here
376
	}
392
	}
377
#endif
393
#endif
378
	coredump = "";
394
	coredump = "";
379
	status = jp->ps[jp->nprocs - 1].status;
395
	status = getjobstatus(jp);
380
	if (jp->state == 0) {
396
	if (jp->state == 0) {
381
		statestr = "Running";
397
		statestr = "Running";
382
#if JOBS
398
#if JOBS
Lines 555-561 waitcmdloop(struct job *job) Link Here
555
	do {
571
	do {
556
		if (job != NULL) {
572
		if (job != NULL) {
557
			if (job->state == JOBDONE) {
573
			if (job->state == JOBDONE) {
558
				status = job->ps[job->nprocs - 1].status;
574
				status = getjobstatus(job);
559
				if (WIFEXITED(status))
575
				if (WIFEXITED(status))
560
					retval = WEXITSTATUS(status);
576
					retval = WEXITSTATUS(status);
561
				else
577
				else
Lines 780-785 makejob(union node *node __unused, int nprocs) Link Here
780
	jp->nprocs = 0;
796
	jp->nprocs = 0;
781
	jp->foreground = 0;
797
	jp->foreground = 0;
782
	jp->remembered = 0;
798
	jp->remembered = 0;
799
	jp->pipefail = pipefailflag;
783
#if JOBS
800
#if JOBS
784
	jp->jobctl = jobctl;
801
	jp->jobctl = jobctl;
785
	jp->next = NULL;
802
	jp->next = NULL;
Lines 1075-1081 waitforjob(struct job *jp, int *signaled) Link Here
1075
	if (jp->state == JOBSTOPPED)
1092
	if (jp->state == JOBSTOPPED)
1076
		setcurjob(jp);
1093
		setcurjob(jp);
1077
#endif
1094
#endif
1078
	status = jp->ps[jp->nprocs - 1].status;
1095
	status = getjobstatus(jp);
1079
	if (signaled != NULL)
1096
	if (signaled != NULL)
1080
		*signaled = WIFSIGNALED(status);
1097
		*signaled = WIFSIGNALED(status);
1081
	/* convert to 8 bits */
1098
	/* convert to 8 bits */
(-)b/bin/sh/options.h (-1 / +3 lines)
Lines 67-75 struct shparam { Link Here
67
#define	Pflag optval[17]
67
#define	Pflag optval[17]
68
#define	hflag optval[18]
68
#define	hflag optval[18]
69
#define	nologflag optval[19]
69
#define	nologflag optval[19]
70
#define	pipefailflag optval[20]
70
71
71
#define NSHORTOPTS	19
72
#define NSHORTOPTS	19
72
#define NOPTS		20
73
#define NOPTS		21
73
74
74
extern char optval[NOPTS];
75
extern char optval[NOPTS];
75
extern const char optletter[NSHORTOPTS];
76
extern const char optletter[NSHORTOPTS];
Lines 97-102 static const unsigned char optname[] = Link Here
97
	"\010physical"
98
	"\010physical"
98
	"\010trackall"
99
	"\010trackall"
99
	"\005nolog"
100
	"\005nolog"
101
	"\010pipefail"
100
;
102
;
101
#endif
103
#endif
102
104
(-)b/bin/sh/sh.1 (-4 / +19 lines)
Lines 348-353 Another do-nothing option for Link Here
348
.Tn POSIX
348
.Tn POSIX
349
compliance.
349
compliance.
350
It only has a long name.
350
It only has a long name.
351
.It Li pipefail
352
Change the exit status of a pipeline to the last non-zero exit status of
353
any command in the pipeline, if any.
354
Since an exit due to
355
.Dv SIGPIPE
356
counts as a non-zero exit status,
357
this option may cause non-zero exit status for successful pipelines
358
if a command such as
359
.Xr head 1
360
in the pipeline terminates with status 0 without reading its
361
input completely.
362
This option only has a long name.
351
.El
363
.El
352
.Pp
364
.Pp
353
The
365
The
Lines 865-876 If the keyword Link Here
865
.Ic !\&
877
.Ic !\&
866
does not precede the pipeline, the
878
does not precede the pipeline, the
867
exit status is the exit status of the last command specified
879
exit status is the exit status of the last command specified
868
in the pipeline.
880
in the pipeline if the
881
.Cm pipefail
882
option is not set or all commands returned zero,
883
or the last non-zero exit status of any command in the pipeline otherwise.
869
Otherwise, the exit status is the logical
884
Otherwise, the exit status is the logical
870
NOT of the exit status of the last command.
885
NOT of that exit status.
871
That is, if
886
That is, if
872
the last command returns zero, the exit status is 1; if
887
that status is zero, the exit status is 1; if
873
the last command returns greater than zero, the exit status
888
that status is greater than zero, the exit status
874
is zero.
889
is zero.
875
.Pp
890
.Pp
876
Because pipeline assignment of standard input or standard
891
Because pipeline assignment of standard input or standard
(-)b/bin/sh/tests/execution/pipefail1.0 (+4 lines)
Added Link Here
1
# $FreeBSD$
2
3
set -o pipefail
4
: && : | : && : | : | : && : | : | : | :
(-)b/bin/sh/tests/execution/pipefail2.42 (+4 lines)
Added Link Here
1
# $FreeBSD$
2
3
set -o pipefail
4
(exit 42) | :
(-)b/bin/sh/tests/execution/pipefail3.42 (+4 lines)
Added Link Here
1
# $FreeBSD$
2
3
set -o pipefail
4
: | (exit 42)
(-)b/bin/sh/tests/execution/pipefail4.42 (+4 lines)
Added Link Here
1
# $FreeBSD$
2
3
set -o pipefail
4
(exit 43) | (exit 42)
(-)b/bin/sh/tests/execution/pipefail5.42 (+5 lines)
Added Link Here
1
# $FreeBSD$
2
3
set -o pipefail
4
(exit 42) | : &
5
wait %+
(-)b/bin/sh/tests/execution/pipefail6.42 (+6 lines)
Added Link Here
1
# $FreeBSD$
2
3
set -o pipefail
4
(exit 42) | : &
5
set +o pipefail
6
wait %+
(-)b/bin/sh/tests/execution/pipefail7.0 (+5 lines)
Added Link Here
1
# $FreeBSD$
2
3
(exit 42) | : &
4
set -o pipefail
5
wait %+

Return to bug 224270