diff options
-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 |