From 775b775240d09fe665efaecf2432d590567e68ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bert=20M=C3=BCnnich?= Date: Fri, 27 Oct 2017 19:30:09 +0200 Subject: Fix exit value for -e with failed backquote or pipeline This fixes rakitzis/rc issue #40. Both cases suffered from a misconception of statprint() in which the necessary check for -e happens. The checked status value gets passed to statprint() as an argument but the corresponding value passed to rc_exit() in case the status is non-zero comes from getstatus(), which requires that the checked status is written to statuses[] first. For pipelines this happened in the wrong order and for backquotes the status value was not put into statuses[] at all. Making statprint() a static helper function prevents this mistake by only leaving the setstatus family of functions to handle status codes. --- glom.c | 2 +- rc.h | 1 - status.c | 6 ++++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/glom.c b/glom.c index c44f0d5..7f90d9d 100644 --- a/glom.c +++ b/glom.c @@ -266,7 +266,7 @@ static List *backq(Node *ifs, Node *n) { bq = bqinput(glom(ifs), p[0]); close(p[0]); rc_wait4(pid, &sp, TRUE); - statprint(-1, sp); + setstatus(-1, sp); varassign("bqstatus", word(strstatus(sp), NULL), FALSE); sigchk(); return bq; diff --git a/rc.h b/rc.h index 2912e60..68d338d 100644 --- a/rc.h +++ b/rc.h @@ -347,7 +347,6 @@ extern void set(bool); extern void setstatus(pid_t, int); extern List *sgetstatus(void); extern void setpipestatus(int [], int); -extern void statprint(pid_t, int); extern void ssetstatus(char **); extern char *strstatus(int s); diff --git a/status.c b/status.c index 5b37aa5..b4e6a05 100644 --- a/status.c +++ b/status.c @@ -7,6 +7,8 @@ /* status == the wait() value of the last command in the pipeline, or the last command */ +static void statprint(pid_t, int); + static int statuses[512]; static int pipelength = 1; @@ -49,8 +51,8 @@ extern void set(bool code) { extern void setpipestatus(int stats[], int num) { int i; for (i = 0; i < (pipelength = num); i++) { - statprint(-1, stats[i]); statuses[i] = stats[i]; + statprint(-1, stats[i]); } } @@ -64,7 +66,7 @@ extern void setstatus(pid_t pid, int i) { /* print a message if termination was with a signal, and if the child dumped core. exit on error if -e is set */ -extern void statprint(pid_t pid, int i) { +static void statprint(pid_t pid, int i) { if (WIFSIGNALED(i)) { int t = WTERMSIG(i); char *msg = ((t > 0) && (t < NUMOFSIGNALS) ? signals[WTERMSIG(i)].msg : ""); -- cgit v1.2.3 From 266dac97fd1cbd2e14cf7a9ca0fda4e446c75e3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bert=20M=C3=BCnnich?= Date: Sat, 28 Oct 2017 13:16:20 +0200 Subject: Add test for issue #40, exit status of -e with failed backquote or pipeline --- trip.rc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/trip.rc b/trip.rc index 1189fb9..5924993 100644 --- a/trip.rc +++ b/trip.rc @@ -614,3 +614,13 @@ if (! ~ $X YYY) { A=``($nl){ $rc -c 'mkdir / >[2=1] | tr a-z A-Z' } B=``($nl){ $rc -c '>[2=1] mkdir / | tr a-z A-Z' } ~ $A $B || fail counter intuitive redirection bug, $A '!=' $B + +# test for github issue #40 +$rc -ec 'false | false' +if (~ $status 0) { + fail '"rc -e" exits with zero status when command in pipeline returns non-zero' +} +$rc -ec 'X=`{false}' +if (~ $status 0) { + fail '"rc -e" exits with zero status when backquote command returns non-zero' +} -- cgit v1.2.3