diff options
Diffstat (limited to 'shell')
| -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 |
