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 */ |