diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-07-26 19:53:11 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-07-26 20:33:51 +0200 |
commit | 981a0568b3f3003cd1a2640ade61d8f5ebdfb865 (patch) | |
tree | e54e9436422569952d0c89ce6e7c79016f64b151 /shell/ash.c | |
parent | d5b500c81c1ec73d2feeea14c2e872726044d9e8 (diff) | |
download | busybox-w32-981a0568b3f3003cd1a2640ade61d8f5ebdfb865.tar.gz busybox-w32-981a0568b3f3003cd1a2640ade61d8f5ebdfb865.tar.bz2 busybox-w32-981a0568b3f3003cd1a2640ade61d8f5ebdfb865.zip |
ash: [VAR] Replace cmdenviron with localvars
Upstream commit:
Date: Wed, 26 May 2010 18:54:19 +0800
[VAR] Replace cmdenviron with localvars
This patch replaces the cmdenviron mechanism for temporary command
variables with the localvars mechanism used by functions.
This reduces code size, and more importantly, makes the variable
assignment take effect immediately as required by POSIX.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell/ash.c')
-rw-r--r-- | shell/ash.c | 61 |
1 files changed, 34 insertions, 27 deletions
diff --git a/shell/ash.c b/shell/ash.c index 75a72ea0c..e900a425f 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -1250,7 +1250,6 @@ static struct parsefile basepf; /* top level input file */ | |||
1250 | static struct parsefile *g_parsefile = &basepf; /* current input file */ | 1250 | static struct parsefile *g_parsefile = &basepf; /* current input file */ |
1251 | static int startlinno; /* line # where last token started */ | 1251 | static int startlinno; /* line # where last token started */ |
1252 | static char *commandname; /* currently executing command */ | 1252 | static char *commandname; /* currently executing command */ |
1253 | static struct strlist *cmdenviron; /* environment for builtin command */ | ||
1254 | 1253 | ||
1255 | 1254 | ||
1256 | /* ============ Message printing */ | 1255 | /* ============ Message printing */ |
@@ -2225,15 +2224,9 @@ reinit_unicode_for_ash(void) | |||
2225 | /* | 2224 | /* |
2226 | * Search the environment of a builtin command. | 2225 | * Search the environment of a builtin command. |
2227 | */ | 2226 | */ |
2228 | static const char * | 2227 | static inline const char * |
2229 | bltinlookup(const char *name) | 2228 | bltinlookup(const char *name) |
2230 | { | 2229 | { |
2231 | struct strlist *sp; | ||
2232 | |||
2233 | for (sp = cmdenviron; sp; sp = sp->next) { | ||
2234 | if (varcmp(sp->text, name) == 0) | ||
2235 | return var_end(sp->text); | ||
2236 | } | ||
2237 | return lookupvar(name); | 2230 | return lookupvar(name); |
2238 | } | 2231 | } |
2239 | 2232 | ||
@@ -9179,7 +9172,7 @@ static struct localvar_list *localvar_stack; | |||
9179 | * Interrupts must be off. | 9172 | * Interrupts must be off. |
9180 | */ | 9173 | */ |
9181 | static void | 9174 | static void |
9182 | poplocalvars(void) | 9175 | poplocalvars(int keep) |
9183 | { | 9176 | { |
9184 | struct localvar_list *ll; | 9177 | struct localvar_list *ll; |
9185 | struct localvar *lvp, *next; | 9178 | struct localvar *lvp, *next; |
@@ -9196,7 +9189,23 @@ poplocalvars(void) | |||
9196 | next = lvp->next; | 9189 | next = lvp->next; |
9197 | vp = lvp->vp; | 9190 | vp = lvp->vp; |
9198 | TRACE(("poplocalvar %s\n", vp ? vp->var_text : "-")); | 9191 | TRACE(("poplocalvar %s\n", vp ? vp->var_text : "-")); |
9199 | if (vp == NULL) { /* $- saved */ | 9192 | if (keep) { |
9193 | int bits = VSTRFIXED; | ||
9194 | |||
9195 | if (lvp->flags != VUNSET) { | ||
9196 | if (vp->var_text == lvp->text) | ||
9197 | bits |= VTEXTFIXED; | ||
9198 | else if (!(lvp->flags & (VTEXTFIXED|VSTACK))) | ||
9199 | free((char*)lvp->text); | ||
9200 | } | ||
9201 | |||
9202 | vp->flags &= ~bits; | ||
9203 | vp->flags |= (lvp->flags & bits); | ||
9204 | |||
9205 | if ((vp->flags & | ||
9206 | (VEXPORT|VREADONLY|VSTRFIXED|VUNSET)) == VUNSET) | ||
9207 | unsetvar(vp->var_text); | ||
9208 | } else if (vp == NULL) { /* $- saved */ | ||
9200 | memcpy(optlist, lvp->text, sizeof(optlist)); | 9209 | memcpy(optlist, lvp->text, sizeof(optlist)); |
9201 | free((char*)lvp->text); | 9210 | free((char*)lvp->text); |
9202 | optschanged(); | 9211 | optschanged(); |
@@ -9260,7 +9269,7 @@ evalfun(struct funcnode *func, int argc, char **argv, int flags) | |||
9260 | #endif | 9269 | #endif |
9261 | pushlocalvars(); | 9270 | pushlocalvars(); |
9262 | evaltree(func->n.narg.next, flags & EV_TESTED); | 9271 | evaltree(func->n.narg.next, flags & EV_TESTED); |
9263 | poplocalvars(); | 9272 | poplocalvars(0); |
9264 | funcdone: | 9273 | funcdone: |
9265 | INT_OFF; | 9274 | INT_OFF; |
9266 | funcnest--; | 9275 | funcnest--; |
@@ -9631,6 +9640,7 @@ evalcommand(union node *cmd, int flags) | |||
9631 | /* First expand the arguments. */ | 9640 | /* First expand the arguments. */ |
9632 | TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags)); | 9641 | TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags)); |
9633 | setstackmark(&smark); | 9642 | setstackmark(&smark); |
9643 | pushlocalvars(); | ||
9634 | back_exitstatus = 0; | 9644 | back_exitstatus = 0; |
9635 | 9645 | ||
9636 | cmdentry.cmdtype = CMDBUILTIN; | 9646 | cmdentry.cmdtype = CMDBUILTIN; |
@@ -9684,6 +9694,8 @@ evalcommand(union node *cmd, int flags) | |||
9684 | spp = varlist.lastp; | 9694 | spp = varlist.lastp; |
9685 | expandarg(argp, &varlist, EXP_VARTILDE); | 9695 | expandarg(argp, &varlist, EXP_VARTILDE); |
9686 | 9696 | ||
9697 | mklocal((*spp)->text); | ||
9698 | |||
9687 | /* | 9699 | /* |
9688 | * Modify the command lookup path, if a PATH= assignment | 9700 | * Modify the command lookup path, if a PATH= assignment |
9689 | * is present | 9701 | * is present |
@@ -9815,6 +9827,7 @@ evalcommand(union node *cmd, int flags) | |||
9815 | /* parent */ | 9827 | /* parent */ |
9816 | status = waitforjob(jp); | 9828 | status = waitforjob(jp); |
9817 | INT_ON; | 9829 | INT_ON; |
9830 | poplocalvars(0); | ||
9818 | TRACE(("forked child exited with %d\n", status)); | 9831 | TRACE(("forked child exited with %d\n", status)); |
9819 | break; | 9832 | break; |
9820 | } | 9833 | } |
@@ -9827,17 +9840,10 @@ evalcommand(union node *cmd, int flags) | |||
9827 | /* NOTREACHED */ | 9840 | /* NOTREACHED */ |
9828 | } /* default */ | 9841 | } /* default */ |
9829 | case CMDBUILTIN: | 9842 | case CMDBUILTIN: |
9830 | cmdenviron = varlist.list; | 9843 | poplocalvars(spclbltin > 0 || argc == 0); |
9831 | if (cmdenviron) { | 9844 | if (cmd_is_exec && argc > 1) |
9832 | struct strlist *list = cmdenviron; | 9845 | listsetvar(varlist.list, VEXPORT); |
9833 | int i = VNOSET; | 9846 | |
9834 | if (spclbltin > 0 || argc == 0) { | ||
9835 | i = 0; | ||
9836 | if (cmd_is_exec && argc > 1) | ||
9837 | i = VEXPORT; | ||
9838 | } | ||
9839 | listsetvar(list, i); | ||
9840 | } | ||
9841 | /* Tight loop with builtins only: | 9847 | /* Tight loop with builtins only: |
9842 | * "while kill -0 $child; do true; done" | 9848 | * "while kill -0 $child; do true; done" |
9843 | * will never exit even if $child died, unless we do this | 9849 | * will never exit even if $child died, unless we do this |
@@ -9855,7 +9861,7 @@ evalcommand(union node *cmd, int flags) | |||
9855 | goto readstatus; | 9861 | goto readstatus; |
9856 | 9862 | ||
9857 | case CMDFUNCTION: | 9863 | case CMDFUNCTION: |
9858 | listsetvar(varlist.list, 0); | 9864 | poplocalvars(1); |
9859 | /* See above for the rationale */ | 9865 | /* See above for the rationale */ |
9860 | dowait(DOWAIT_NONBLOCK, NULL); | 9866 | dowait(DOWAIT_NONBLOCK, NULL); |
9861 | if (evalfun(cmdentry.u.func, argc, argv, flags)) | 9867 | if (evalfun(cmdentry.u.func, argc, argv, flags)) |
@@ -12714,11 +12720,12 @@ dotcmd(int argc_ UNUSED_PARAM, char **argv_ UNUSED_PARAM) | |||
12714 | char *fullname; | 12720 | char *fullname; |
12715 | char **argv; | 12721 | char **argv; |
12716 | char *args_need_save; | 12722 | char *args_need_save; |
12717 | struct strlist *sp; | ||
12718 | volatile struct shparam saveparam; | 12723 | volatile struct shparam saveparam; |
12719 | 12724 | ||
12720 | for (sp = cmdenviron; sp; sp = sp->next) | 12725 | //??? |
12721 | setvareq(ckstrdup(sp->text), VSTRFIXED | VTEXTFIXED); | 12726 | // struct strlist *sp; |
12727 | // for (sp = cmdenviron; sp; sp = sp->next) | ||
12728 | // setvareq(ckstrdup(sp->text), VSTRFIXED | VTEXTFIXED); | ||
12722 | 12729 | ||
12723 | nextopt(nullstr); /* handle possible "--" */ | 12730 | nextopt(nullstr); /* handle possible "--" */ |
12724 | argv = argptr; | 12731 | argv = argptr; |
@@ -13601,7 +13608,7 @@ reset(void) | |||
13601 | 13608 | ||
13602 | /* from var.c: */ | 13609 | /* from var.c: */ |
13603 | while (localvar_stack) | 13610 | while (localvar_stack) |
13604 | poplocalvars(); | 13611 | poplocalvars(0); |
13605 | } | 13612 | } |
13606 | 13613 | ||
13607 | #if PROFILE | 13614 | #if PROFILE |