aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2020-02-20 16:47:01 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2020-02-20 16:47:01 +0100
commitcd24a506336f84ff2bb3318bc4f2f82dd025f318 (patch)
tree4b05a48e5211faae670afb7671452a59ab0a89d5
parentbb095f483827567452ee3501779a84f36719288d (diff)
downloadbusybox-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.c23
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)
9094static smallint evalskip; /* set to SKIPxxx if we are skipping commands */ 9095static smallint evalskip; /* set to SKIPxxx if we are skipping commands */
9095static int skipcount; /* number of levels to skip */ 9096static int skipcount; /* number of levels to skip */
9096static int loopnest; /* current loop nesting level */ 9097static 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)
9928static int FAST_FUNC 9930static int FAST_FUNC
9929returncmd(int argc UNUSED_PARAM, char **argv) 9931returncmd(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 }