aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--shell/ash.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 7acb33e7e..d38378411 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);