diff options
-rw-r--r-- | shell/ash.c | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/shell/ash.c b/shell/ash.c index 7acb33e..d383784 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -5663,19 +5663,22 @@ ifsbreakup(char *string, struct arglist *arglist) static void ifsfree(void) { - struct ifsregion *p; + struct ifsregion *p = ifsfirst.next; + + if (!p) + goto out; INT_OFF; - p = ifsfirst.next; do { struct ifsregion *ifsp; ifsp = p->next; free(p); p = ifsp; } while (p); - ifslastp = NULL; ifsfirst.next = NULL; INT_ON; + out: + ifslastp = NULL; } static size_t @@ -5989,6 +5992,7 @@ evalbackcmd(union node *n, struct backcmd *result) * For now, preserve bash-like behavior, it seems to be somewhat more useful: */ eflag = 0; + ifsfree(); evaltree(n, EV_EXIT); /* actually evaltreenr... */ /* NOTREACHED */ } @@ -7296,15 +7300,14 @@ expandarg(union node *arg, struct arglist *arglist, int flag) argbackq = arg->narg.backquote; STARTSTACKSTR(expdest); - ifsfirst.next = NULL; - ifslastp = NULL; TRACE(("expandarg: argstr('%s',flags:%x)\n", arg->narg.text, flag)); argstr(arg->narg.text, flag, /* var_str_list: */ arglist ? arglist->list : NULL); p = _STPUTC('\0', expdest); expdest = p - 1; if (arglist == NULL) { - return; /* here document expanded */ + /* here document expanded */ + goto out; } p = grabstackstr(p); TRACE(("expandarg: p:'%s'\n", p)); @@ -7327,13 +7330,14 @@ expandarg(union node *arg, struct arglist *arglist, int flag) *exparg.lastp = sp; exparg.lastp = &sp->next; } - if (ifsfirst.next) - ifsfree(); *exparg.lastp = NULL; if (exparg.list) { *arglist->lastp = exparg.list; arglist->lastp = exparg.lastp; } + + out: + ifsfree(); } /* @@ -7367,10 +7371,10 @@ casematch(union node *pattern, char *val) setstackmark(&smark); argbackq = pattern->narg.backquote; STARTSTACKSTR(expdest); - ifslastp = NULL; argstr(pattern->narg.text, EXP_TILDE | EXP_CASE, /* var_str_list: */ NULL); STACKSTRNUL(expdest); + ifsfree(); result = patmatch(stackblock(), val); popstackmark(&smark); return result; @@ -13293,6 +13297,7 @@ read_profile(const char *name) /* * This routine is called when an error or an interrupt occurs in an * interactive shell and control is returned to the main command loop. + * (In dash, this function is auto-generated by build machinery). */ static void reset(void) @@ -13300,13 +13305,19 @@ reset(void) /* from eval.c: */ evalskip = 0; loopnest = 0; + + /* from expand.c: */ + ifsfree(); + /* from input.c: */ g_parsefile->left_in_buffer = 0; g_parsefile->left_in_line = 0; /* clear input buffer */ popallfiles(); + /* from parser.c: */ tokpushback = 0; checkkwd = 0; + /* from redir.c: */ while (redirlist) popredir(/*drop:*/ 0, /*restore:*/ 0); |