@@ -714,6 +714,7 @@ evalcommand(union node *cmd, int flags)
int execcmd;
int status;
char **nargv;
+ int vflags;
errlinno = lineno = cmd->ncmd.linno;
if (funcline)
@@ -769,8 +770,6 @@ evalcommand(union node *cmd, int flags)
spp = varlist.lastp;
expandarg(argp, &varlist, EXP_VARTILDE);
- mklocal((*spp)->text);
-
/*
* Modify the command lookup path, if a PATH= assignment
* is present
@@ -852,6 +851,13 @@ bail:
jp = NULL;
+ if (cmdentry.cmdtype == CMDBUILTIN && (spclbltin > 0 || argc == 0))
+ vflags = execcmd && argc > 1 ? VEXPORT : 0;
+ else
+ vflags = VLOCAL | (cmdentry.cmdtype == CMDNORMAL ?
+ VEXPORT | VNOFUNC : 0);
+ listsetvar(varlist.list, vflags);
+
/* Execute the command. */
switch (cmdentry.cmdtype) {
default:
@@ -863,16 +869,10 @@ bail:
break;
FORCEINTON;
}
- listsetvar(varlist.list, VEXPORT|VSTACK);
shellexec(argv, path, cmdentry.u.index);
/* NOTREACHED */
case CMDBUILTIN:
- if (spclbltin > 0 || argc == 0) {
- poplocalvars(1);
- if (execcmd && argc > 1)
- listsetvar(varlist.list, VEXPORT);
- }
if (evalbltin(cmdentry.u.cmd, argc, argv, flags) &&
!(exception == EXERROR && spclbltin <= 0)) {
raise:
@@ -116,6 +116,7 @@ STATIC struct var *vartab[VTABSIZE];
STATIC struct var **hashvar(const char *);
STATIC int vpcmp(const void *, const void *);
STATIC struct var **findvar(struct var **, const char *);
+static void mklocal(char *name, int flags);
/*
* Initialize the varable symbol tables and import the environment
@@ -325,7 +326,10 @@ listsetvar(struct strlist *list, int flags)
return;
INTOFF;
do {
- setvareq(lp->text, flags);
+ if (flags & VLOCAL)
+ mklocal(lp->text, flags & ~VLOCAL);
+ else
+ setvareq(lp->text, flags);
} while ((lp = lp->next));
INTON;
}
@@ -475,7 +479,7 @@ localcmd(int argc, char **argv)
argv = argptr;
while ((name = *argv++) != NULL) {
- mklocal(name);
+ mklocal(name, 0);
}
return 0;
}
@@ -488,7 +492,7 @@ localcmd(int argc, char **argv)
* "-" as a special case.
*/
-void mklocal(char *name)
+static void mklocal(char *name, int flags)
{
struct localvar *lvp;
struct var **vpp;
@@ -509,16 +513,16 @@ void mklocal(char *name)
eq = strchr(name, '=');
if (vp == NULL) {
if (eq)
- vp = setvareq(name, VSTRFIXED);
+ vp = setvareq(name, VSTRFIXED | flags);
else
- vp = setvar(name, NULL, VSTRFIXED);
+ vp = setvar(name, NULL, VSTRFIXED | flags);
lvp->flags = VUNSET;
} else {
lvp->text = vp->text;
lvp->flags = vp->flags;
vp->flags |= VSTRFIXED|VTEXTFIXED;
if (eq)
- setvareq(name, 0);
+ setvareq(name, flags);
}
}
lvp->vp = vp;
@@ -50,6 +50,7 @@
#define VNOFUNC 0x40 /* don't call the callback function */
#define VNOSET 0x80 /* do not set variable - just readonly test */
#define VNOSAVE 0x100 /* when text is on the heap before setvareq */
+#define VLOCAL 0x200 /* Tell listsetvar to call mklocal */
struct var {
@@ -151,7 +152,6 @@ char **listvars(int, int, char ***);
int showvars(const char *, int, int);
int exportcmd(int, char **);
int localcmd(int, char **);
-void mklocal(char *);
struct localvar_list *pushlocalvars(void);
void poplocalvars(int);
void unwindlocalvars(struct localvar_list *stop);
This patch adds support for listsetvar to be used for setting local variables in bulk through the VLOCAL flag. It also removes the use of mklocal in evalcommand, and replaces it with listsetvar. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>