diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2020-02-19 17:33:44 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2020-02-20 09:36:51 +0100 |
commit | 3e729102a86b1fb536f61c6ebcd95321ba98528d (patch) | |
tree | 0624e6d0c39f564ad18b4eac3fa1e590eadd7f0b | |
parent | 54bef2a8efd21e9992a9d26cf30c5b26cbc0e21a (diff) | |
download | busybox-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.c | 63 |
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 | */ | ||
2482 | static void | ||
2483 | listsetvar(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 | */ |
9812 | static void | 9794 | static void |
9813 | mklocal(char *name) | 9795 | mklocal(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... |