aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2020-02-19 17:33:44 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2020-02-20 09:36:51 +0100
commit3e729102a86b1fb536f61c6ebcd95321ba98528d (patch)
tree0624e6d0c39f564ad18b4eac3fa1e590eadd7f0b
parent54bef2a8efd21e9992a9d26cf30c5b26cbc0e21a (diff)
downloadbusybox-w32-3e729102a86b1fb536f61c6ebcd95321ba98528d.tar.gz
busybox-w32-3e729102a86b1fb536f61c6ebcd95321ba98528d.tar.bz2
busybox-w32-3e729102a86b1fb536f61c6ebcd95321ba98528d.zip
ash: eval: Replace with listsetvar with mklocal/setvareq
Upstream commit: Date: Sat, 19 May 2018 02:39:55 +0800 eval: Replace with listsetvar with mklocal/setvareq This patch replaces listsetvar with mklocal/setvareq. As we now determine special built-in status prior to variable assignment, we no longer have to do a second pass listsetvar. Instead we will call setvareq directly instead of mklocal when necessary. In order to do this mklocal can now take a flag in order to mark a variable for export. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--shell/ash.c63
1 files changed, 28 insertions, 35 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 5570057e9..5bb10e5cb 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -2477,24 +2477,6 @@ unsetvar(const char *s)
2477} 2477}
2478 2478
2479/* 2479/*
2480 * Process a linked list of variable assignments.
2481 */
2482static void
2483listsetvar(struct strlist *list_set_var, int flags)
2484{
2485 struct strlist *lp = list_set_var;
2486
2487 if (!lp)
2488 return;
2489 INT_OFF;
2490 do {
2491 setvareq(lp->text, flags);
2492 lp = lp->next;
2493 } while (lp);
2494 INT_ON;
2495}
2496
2497/*
2498 * Generate a list of variables satisfying the given conditions. 2480 * Generate a list of variables satisfying the given conditions.
2499 */ 2481 */
2500#if !ENABLE_FEATURE_SH_NOFORK 2482#if !ENABLE_FEATURE_SH_NOFORK
@@ -9810,7 +9792,7 @@ evalfun(struct funcnode *func, int argc, char **argv, int flags)
9810 * (options will be restored on return from the function). 9792 * (options will be restored on return from the function).
9811 */ 9793 */
9812static void 9794static void
9813mklocal(char *name) 9795mklocal(char *name, int flags)
9814{ 9796{
9815 struct localvar *lvp; 9797 struct localvar *lvp;
9816 struct var **vpp; 9798 struct var **vpp;
@@ -9847,9 +9829,9 @@ mklocal(char *name)
9847 if (vp == NULL) { 9829 if (vp == NULL) {
9848 /* variable did not exist yet */ 9830 /* variable did not exist yet */
9849 if (eq) 9831 if (eq)
9850 vp = setvareq(name, VSTRFIXED); 9832 vp = setvareq(name, VSTRFIXED | flags);
9851 else 9833 else
9852 vp = setvar(name, NULL, VSTRFIXED); 9834 vp = setvar(name, NULL, VSTRFIXED | flags);
9853 lvp->flags = VUNSET; 9835 lvp->flags = VUNSET;
9854 } else { 9836 } else {
9855 lvp->text = vp->var_text; 9837 lvp->text = vp->var_text;
@@ -9859,7 +9841,7 @@ mklocal(char *name)
9859 */ 9841 */
9860 vp->flags |= VSTRFIXED|VTEXTFIXED; 9842 vp->flags |= VSTRFIXED|VTEXTFIXED;
9861 if (eq) 9843 if (eq)
9862 setvareq(name, 0); 9844 setvareq(name, flags);
9863 else 9845 else
9864 /* "local VAR" unsets VAR: */ 9846 /* "local VAR" unsets VAR: */
9865 setvar0(name, NULL); 9847 setvar0(name, NULL);
@@ -9885,7 +9867,7 @@ localcmd(int argc UNUSED_PARAM, char **argv)
9885 9867
9886 argv = argptr; 9868 argv = argptr;
9887 while ((name = *argv++) != NULL) { 9869 while ((name = *argv++) != NULL) {
9888 mklocal(name); 9870 mklocal(name, 0);
9889 } 9871 }
9890 return 0; 9872 return 0;
9891} 9873}
@@ -10166,6 +10148,8 @@ evalcommand(union node *cmd, int flags)
10166 int status; 10148 int status;
10167 char **nargv; 10149 char **nargv;
10168 smallint cmd_is_exec; 10150 smallint cmd_is_exec;
10151 int vflags;
10152 int vlocal;
10169 10153
10170 errlinno = lineno = cmd->ncmd.linno; 10154 errlinno = lineno = cmd->ncmd.linno;
10171 if (funcline) 10155 if (funcline)
@@ -10173,7 +10157,6 @@ evalcommand(union node *cmd, int flags)
10173 10157
10174 /* First expand the arguments. */ 10158 /* First expand the arguments. */
10175 TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags)); 10159 TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
10176 localvar_stop = pushlocalvars();
10177 file_stop = g_parsefile; 10160 file_stop = g_parsefile;
10178 back_exitstatus = 0; 10161 back_exitstatus = 0;
10179 10162
@@ -10187,6 +10170,8 @@ evalcommand(union node *cmd, int flags)
10187 cmd_flag = 0; 10170 cmd_flag = 0;
10188 cmd_is_exec = 0; 10171 cmd_is_exec = 0;
10189 spclbltin = -1; 10172 spclbltin = -1;
10173 vflags = 0;
10174 vlocal = 0;
10190 path = NULL; 10175 path = NULL;
10191 10176
10192 argc = 0; 10177 argc = 0;
@@ -10199,6 +10184,8 @@ evalcommand(union node *cmd, int flags)
10199 find_command(arglist.list->text, &cmdentry, 10184 find_command(arglist.list->text, &cmdentry,
10200 cmd_flag | DO_REGBLTIN, pathval()); 10185 cmd_flag | DO_REGBLTIN, pathval());
10201 10186
10187 vlocal++;
10188
10202 /* implement bltin and command here */ 10189 /* implement bltin and command here */
10203 if (cmdentry.cmdtype != CMDBUILTIN) 10190 if (cmdentry.cmdtype != CMDBUILTIN)
10204 break; 10191 break;
@@ -10206,6 +10193,7 @@ evalcommand(union node *cmd, int flags)
10206 pseudovarflag = IS_BUILTIN_ASSIGN(cmdentry.u.cmd); 10193 pseudovarflag = IS_BUILTIN_ASSIGN(cmdentry.u.cmd);
10207 if (spclbltin < 0) { 10194 if (spclbltin < 0) {
10208 spclbltin = IS_BUILTIN_SPECIAL(cmdentry.u.cmd); 10195 spclbltin = IS_BUILTIN_SPECIAL(cmdentry.u.cmd);
10196 vlocal = !spclbltin;
10209 } 10197 }
10210 cmd_is_exec = cmdentry.u.cmd == EXECCMD; 10198 cmd_is_exec = cmdentry.u.cmd == EXECCMD;
10211 if (cmdentry.u.cmd != COMMANDCMD) 10199 if (cmdentry.u.cmd != COMMANDCMD)
@@ -10224,6 +10212,9 @@ evalcommand(union node *cmd, int flags)
10224 10212
10225 for (sp = arglist.list; sp; sp = sp->next) 10213 for (sp = arglist.list; sp; sp = sp->next)
10226 argc++; 10214 argc++;
10215
10216 if (cmd_is_exec && argc > 1)
10217 vflags = VEXPORT;
10227 } 10218 }
10228 10219
10229 /* Reserve one extra spot at the front for shellexec. */ 10220 /* Reserve one extra spot at the front for shellexec. */
@@ -10254,6 +10245,7 @@ evalcommand(union node *cmd, int flags)
10254 status = redirectsafe(cmd->ncmd.redirect, REDIR_PUSH | REDIR_SAVEFD2); 10245 status = redirectsafe(cmd->ncmd.redirect, REDIR_PUSH | REDIR_SAVEFD2);
10255 10246
10256 if (status) { 10247 if (status) {
10248 vlocal = 0;
10257 bail: 10249 bail:
10258 exitstatus = status; 10250 exitstatus = status;
10259 10251
@@ -10264,13 +10256,20 @@ evalcommand(union node *cmd, int flags)
10264 goto out; 10256 goto out;
10265 } 10257 }
10266 10258
10259 localvar_stop = NULL;
10260 if (vlocal)
10261 localvar_stop = pushlocalvars();
10262
10267 for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) { 10263 for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) {
10268 struct strlist **spp; 10264 struct strlist **spp;
10269 10265
10270 spp = varlist.lastp; 10266 spp = varlist.lastp;
10271 expandarg(argp, &varlist, EXP_VARTILDE); 10267 expandarg(argp, &varlist, EXP_VARTILDE);
10272 10268
10273 mklocal((*spp)->text); 10269 if (vlocal)
10270 mklocal((*spp)->text, VEXPORT);
10271 else
10272 setvareq((*spp)->text, vflags);
10274 } 10273 }
10275 10274
10276 /* Print the command if xflag is set. */ 10275 /* Print the command if xflag is set. */
@@ -10313,8 +10312,8 @@ evalcommand(union node *cmd, int flags)
10313 if (cmdentry.cmdtype != CMDBUILTIN 10312 if (cmdentry.cmdtype != CMDBUILTIN
10314 || !(IS_BUILTIN_REGULAR(cmdentry.u.cmd)) 10313 || !(IS_BUILTIN_REGULAR(cmdentry.u.cmd))
10315 ) { 10314 ) {
10316 find_command(argv[0], &cmdentry, cmd_flag | DO_ERR, 10315 path = path ? path : pathval();
10317 path ? path : pathval()); 10316 find_command(argv[0], &cmdentry, cmd_flag | DO_ERR, path);
10318 } 10317 }
10319 10318
10320 jp = NULL; 10319 jp = NULL;
@@ -10385,17 +10384,10 @@ evalcommand(union node *cmd, int flags)
10385 FORCE_INT_ON; 10384 FORCE_INT_ON;
10386 /* fall through to exec'ing external program */ 10385 /* fall through to exec'ing external program */
10387 } 10386 }
10388 listsetvar(varlist.list, VEXPORT|VSTACK);
10389 path = path ? path : pathval();
10390 shellexec(argv[0], argv, path, cmdentry.u.index); 10387 shellexec(argv[0], argv, path, cmdentry.u.index);
10391 /* NOTREACHED */ 10388 /* NOTREACHED */
10392 } /* default */ 10389 } /* default */
10393 case CMDBUILTIN: 10390 case CMDBUILTIN:
10394 if (spclbltin > 0 || argc == 0) {
10395 poplocalvars(1);
10396 if (cmd_is_exec && argc > 1)
10397 listsetvar(varlist.list, VEXPORT);
10398 }
10399 if (evalbltin(cmdentry.u.cmd, argc, argv, flags) 10391 if (evalbltin(cmdentry.u.cmd, argc, argv, flags)
10400 && !(exception_type == EXERROR && spclbltin <= 0) 10392 && !(exception_type == EXERROR && spclbltin <= 0)
10401 ) { 10393 ) {
@@ -10418,7 +10410,8 @@ evalcommand(union node *cmd, int flags)
10418 popredir(/*drop:*/ cmd_is_exec); 10410 popredir(/*drop:*/ cmd_is_exec);
10419 unwindredir(redir_stop); 10411 unwindredir(redir_stop);
10420 unwindfiles(file_stop); 10412 unwindfiles(file_stop);
10421 unwindlocalvars(localvar_stop); 10413 if (vlocal)
10414 unwindlocalvars(localvar_stop);
10422 if (lastarg) { 10415 if (lastarg) {
10423 /* dsl: I think this is intended to be used to support 10416 /* dsl: I think this is intended to be used to support
10424 * '_' in 'vi' command mode during line editing... 10417 * '_' in 'vi' command mode during line editing...