diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2020-02-20 16:47:01 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2020-02-20 16:47:01 +0100 |
commit | cd24a506336f84ff2bb3318bc4f2f82dd025f318 (patch) | |
tree | 4b05a48e5211faae670afb7671452a59ab0a89d5 | |
parent | bb095f483827567452ee3501779a84f36719288d (diff) | |
download | busybox-w32-cd24a506336f84ff2bb3318bc4f2f82dd025f318.tar.gz busybox-w32-cd24a506336f84ff2bb3318bc4f2f82dd025f318.tar.bz2 busybox-w32-cd24a506336f84ff2bb3318bc4f2f82dd025f318.zip |
ash: Return without arguments in a trap should use status outside traps
Fixes exitcode_trap4.tests.
Upstream commit:
Date: Mon, 6 Oct 2014 21:51:26 +0800
Return without arguments in a trap should use status outside traps
POSIX now requires that return without arguments in a trap should
return the last command status prior to executing traps. This
patch implements this behaviour.
Incidentally this also changes the behaviour of return without
arguments in a loop conditional to use the last exit status in
the body as opposed to the last command in the conditional when
there is one.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | shell/ash.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/shell/ash.c b/shell/ash.c index a6f777800..bea24601c 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -9091,6 +9091,7 @@ defun(union node *func) | |||
9091 | #define SKIPBREAK (1 << 0) | 9091 | #define SKIPBREAK (1 << 0) |
9092 | #define SKIPCONT (1 << 1) | 9092 | #define SKIPCONT (1 << 1) |
9093 | #define SKIPFUNC (1 << 2) | 9093 | #define SKIPFUNC (1 << 2) |
9094 | #define SKIPFUNCDEF (1 << 3) | ||
9094 | static smallint evalskip; /* set to SKIPxxx if we are skipping commands */ | 9095 | static smallint evalskip; /* set to SKIPxxx if we are skipping commands */ |
9095 | static int skipcount; /* number of levels to skip */ | 9096 | static int skipcount; /* number of levels to skip */ |
9096 | static int loopnest; /* current loop nesting level */ | 9097 | static int loopnest; /* current loop nesting level */ |
@@ -9148,7 +9149,8 @@ dotrap(void) | |||
9148 | if (!p) | 9149 | if (!p) |
9149 | continue; | 9150 | continue; |
9150 | evalstring(p, 0); | 9151 | evalstring(p, 0); |
9151 | exitstatus = status; | 9152 | if (evalskip != SKIPFUNC) |
9153 | exitstatus = status; | ||
9152 | } | 9154 | } |
9153 | 9155 | ||
9154 | savestatus = last_status; | 9156 | savestatus = last_status; |
@@ -9783,7 +9785,7 @@ evalfun(struct funcnode *func, int argc, char **argv, int flags) | |||
9783 | shellparam = saveparam; | 9785 | shellparam = saveparam; |
9784 | exception_handler = savehandler; | 9786 | exception_handler = savehandler; |
9785 | INT_ON; | 9787 | INT_ON; |
9786 | evalskip &= ~SKIPFUNC; | 9788 | evalskip &= ~(SKIPFUNC | SKIPFUNCDEF); |
9787 | return e; | 9789 | return e; |
9788 | } | 9790 | } |
9789 | 9791 | ||
@@ -9928,12 +9930,23 @@ execcmd(int argc UNUSED_PARAM, char **argv) | |||
9928 | static int FAST_FUNC | 9930 | static int FAST_FUNC |
9929 | returncmd(int argc UNUSED_PARAM, char **argv) | 9931 | returncmd(int argc UNUSED_PARAM, char **argv) |
9930 | { | 9932 | { |
9933 | int skip; | ||
9934 | int status; | ||
9935 | |||
9931 | /* | 9936 | /* |
9932 | * If called outside a function, do what ksh does; | 9937 | * If called outside a function, do what ksh does; |
9933 | * skip the rest of the file. | 9938 | * skip the rest of the file. |
9934 | */ | 9939 | */ |
9935 | evalskip = SKIPFUNC; | 9940 | if (argv[1]) { |
9936 | return argv[1] ? number(argv[1]) : exitstatus; | 9941 | skip = SKIPFUNC; |
9942 | status = number(argv[1]); | ||
9943 | } else { | ||
9944 | skip = SKIPFUNCDEF; | ||
9945 | status = exitstatus; | ||
9946 | } | ||
9947 | evalskip = skip; | ||
9948 | |||
9949 | return status; | ||
9937 | } | 9950 | } |
9938 | 9951 | ||
9939 | /* Forward declarations for builtintab[] */ | 9952 | /* Forward declarations for builtintab[] */ |
@@ -13372,7 +13385,7 @@ cmdloop(int top) | |||
13372 | skip = evalskip; | 13385 | skip = evalskip; |
13373 | 13386 | ||
13374 | if (skip) { | 13387 | if (skip) { |
13375 | evalskip &= ~SKIPFUNC; | 13388 | evalskip &= ~(SKIPFUNC | SKIPFUNCDEF); |
13376 | break; | 13389 | break; |
13377 | } | 13390 | } |
13378 | } | 13391 | } |