aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-07-26 19:55:31 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2017-07-26 20:33:51 +0200
commit484fc2056df8a82acabc70386eeb6d0da4982fec (patch)
tree6fb274f54567084fde08d667e7d6183f2971e85f
parent981a0568b3f3003cd1a2640ade61d8f5ebdfb865 (diff)
downloadbusybox-w32-484fc2056df8a82acabc70386eeb6d0da4982fec.tar.gz
busybox-w32-484fc2056df8a82acabc70386eeb6d0da4982fec.tar.bz2
busybox-w32-484fc2056df8a82acabc70386eeb6d0da4982fec.zip
ash: [VAR] Fix poplocalvar on abnormal exit from function
Upstream commit: Date: Thu, 27 May 2010 11:32:55 +0800 [VAR] Fix poplocalvar on abnormal exit from function The new localvar code broke the abnormal exit from functions and built-ins by not restoring the original localvar state. This patch fixes this by storing the previous localvar state so that we always unwind correctly in case of an abnormal exit. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--shell/ash.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/shell/ash.c b/shell/ash.c
index e900a425f..f7fc18f0d 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -9228,7 +9228,7 @@ poplocalvars(int keep)
9228/* 9228/*
9229 * Create a new localvar environment. 9229 * Create a new localvar environment.
9230 */ 9230 */
9231static void 9231static struct localvar_list *
9232pushlocalvars(void) 9232pushlocalvars(void)
9233{ 9233{
9234 struct localvar_list *ll; 9234 struct localvar_list *ll;
@@ -9239,6 +9239,15 @@ pushlocalvars(void)
9239 ll->next = localvar_stack; 9239 ll->next = localvar_stack;
9240 localvar_stack = ll; 9240 localvar_stack = ll;
9241 INT_ON; 9241 INT_ON;
9242
9243 return ll->next;
9244}
9245
9246static void
9247unwindlocalvars(struct localvar_list *stop)
9248{
9249 while (localvar_stack != stop)
9250 poplocalvars(0);
9242} 9251}
9243 9252
9244static int 9253static int
@@ -9619,6 +9628,7 @@ evalcommand(union node *cmd, int flags)
9619 static const struct builtincmd null_bltin = { 9628 static const struct builtincmd null_bltin = {
9620 "\0\0", bltincmd /* why three NULs? */ 9629 "\0\0", bltincmd /* why three NULs? */
9621 }; 9630 };
9631 struct localvar_list *localvar_stop;
9622 struct stackmark smark; 9632 struct stackmark smark;
9623 union node *argp; 9633 union node *argp;
9624 struct arglist arglist; 9634 struct arglist arglist;
@@ -9640,7 +9650,7 @@ evalcommand(union node *cmd, int flags)
9640 /* First expand the arguments. */ 9650 /* First expand the arguments. */
9641 TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags)); 9651 TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
9642 setstackmark(&smark); 9652 setstackmark(&smark);
9643 pushlocalvars(); 9653 localvar_stop = pushlocalvars();
9644 back_exitstatus = 0; 9654 back_exitstatus = 0;
9645 9655
9646 cmdentry.cmdtype = CMDBUILTIN; 9656 cmdentry.cmdtype = CMDBUILTIN;
@@ -9827,7 +9837,6 @@ evalcommand(union node *cmd, int flags)
9827 /* parent */ 9837 /* parent */
9828 status = waitforjob(jp); 9838 status = waitforjob(jp);
9829 INT_ON; 9839 INT_ON;
9830 poplocalvars(0);
9831 TRACE(("forked child exited with %d\n", status)); 9840 TRACE(("forked child exited with %d\n", status));
9832 break; 9841 break;
9833 } 9842 }
@@ -9874,6 +9883,7 @@ evalcommand(union node *cmd, int flags)
9874 out: 9883 out:
9875 if (cmd->ncmd.redirect) 9884 if (cmd->ncmd.redirect)
9876 popredir(/*drop:*/ cmd_is_exec, /*restore:*/ cmd_is_exec); 9885 popredir(/*drop:*/ cmd_is_exec, /*restore:*/ cmd_is_exec);
9886 unwindlocalvars(localvar_stop);
9877 if (lastarg) { 9887 if (lastarg) {
9878 /* dsl: I think this is intended to be used to support 9888 /* dsl: I think this is intended to be used to support
9879 * '_' in 'vi' command mode during line editing... 9889 * '_' in 'vi' command mode during line editing...
@@ -13607,8 +13617,7 @@ reset(void)
13607 popredir(/*drop:*/ 0, /*restore:*/ 0); 13617 popredir(/*drop:*/ 0, /*restore:*/ 0);
13608 13618
13609 /* from var.c: */ 13619 /* from var.c: */
13610 while (localvar_stack) 13620 unwindlocalvars(NULL);
13611 poplocalvars(0);
13612} 13621}
13613 13622
13614#if PROFILE 13623#if PROFILE