aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2010-05-26 18:54:19 +0800
committermaximilian attems <max@stro.at>2011-06-03 18:04:49 +0200
commitb315f1cb18435f3f6d827af37a045cb6186f4ff2 (patch)
treefdd15d5ed056b5a737858a787934a0586a38e3c0
parentdbf2ff1a875c2ca8c4a3144874ca2883e55e7eeb (diff)
downloadklibc-b315f1cb18435f3f6d827af37a045cb6186f4ff2.tar.gz
[klibc] [VAR] Replace cmdenviron with localvars
This patch replaces the cmdenviron mechanism for temporary command variables with the localvars mechanism used by functions. This reduces code size, and more importantly, makes the variable assignment take effect immediately as required by POSIX. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: maximilian attems <max@stro.at>
-rw-r--r--usr/dash/eval.c23
-rw-r--r--usr/dash/eval.h1
-rw-r--r--usr/dash/var.c45
-rw-r--r--usr/dash/var.h13
4 files changed, 40 insertions, 42 deletions
diff --git a/usr/dash/eval.c b/usr/dash/eval.c
index e3737e9e76268..1c5d13e76da1c 100644
--- a/usr/dash/eval.c
+++ b/usr/dash/eval.c
@@ -77,7 +77,6 @@ static int funcnest; /* depth of function calls */
char *commandname;
-struct strlist *cmdenviron;
int exitstatus; /* exit status of last command */
int back_exitstatus; /* exit status of backquoted command */
@@ -704,6 +703,7 @@ evalcommand(union node *cmd, int flags)
/* First expand the arguments. */
TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
setstackmark(&smark);
+ pushlocalvars();
back_exitstatus = 0;
cmdentry.cmdtype = CMDBUILTIN;
@@ -748,6 +748,8 @@ 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
@@ -835,6 +837,7 @@ bail:
if (forkshell(jp, cmd, FORK_FG) != 0) {
exitstatus = waitforjob(jp);
INTON;
+ poplocalvars(0);
break;
}
FORCEINTON;
@@ -844,17 +847,9 @@ bail:
/* NOTREACHED */
case CMDBUILTIN:
- cmdenviron = varlist.list;
- if (cmdenviron) {
- struct strlist *list = cmdenviron;
- int i = VNOSET;
- if (spclbltin > 0 || argc == 0) {
- i = 0;
- if (execcmd && argc > 1)
- i = VEXPORT;
- }
- listsetvar(list, i);
- }
+ poplocalvars(spclbltin > 0 || argc == 0);
+ if (execcmd && argc > 1)
+ listsetvar(varlist.list, VEXPORT);
if (evalbltin(cmdentry.u.cmd, argc, argv, flags)) {
int status;
int i;
@@ -875,7 +870,7 @@ raise:
break;
case CMDFUNCTION:
- listsetvar(varlist.list, 0);
+ poplocalvars(1);
if (evalfun(cmdentry.u.func, argc, argv, flags))
goto raise;
break;
@@ -949,7 +944,7 @@ evalfun(struct funcnode *func, int argc, char **argv, int flags)
shellparam.optoff = -1;
pushlocalvars();
evaltree(&func->n, flags & EV_TESTED);
- poplocalvars();
+ poplocalvars(0);
funcdone:
INTOFF;
funcnest--;
diff --git a/usr/dash/eval.h b/usr/dash/eval.h
index e190b28ae4466..ac394e8fc445d 100644
--- a/usr/dash/eval.h
+++ b/usr/dash/eval.h
@@ -37,7 +37,6 @@
extern char *commandname; /* currently executing command */
extern int exitstatus; /* exit status of last command */
extern int back_exitstatus; /* exit status of backquoted command */
-extern struct strlist *cmdenviron; /* environment for builtin command */
struct backcmd { /* result of evalbackcmd */
diff --git a/usr/dash/var.c b/usr/dash/var.c
index 12f2f6c65e531..40bd3fdce2c2e 100644
--- a/usr/dash/var.c
+++ b/usr/dash/var.c
@@ -44,7 +44,6 @@
#include "output.h"
#include "expand.h"
#include "nodes.h" /* for other headers */
-#include "eval.h" /* defines cmdenviron */
#include "exec.h"
#include "syntax.h"
#include "options.h"
@@ -104,7 +103,6 @@ struct var varinit[] = {
STATIC struct var *vartab[VTABSIZE];
-STATIC void mklocal(char *);
STATIC struct var **hashvar(const char *);
STATIC int vpcmp(const void *, const void *);
STATIC struct var **findvar(struct var **, const char *);
@@ -147,7 +145,7 @@ INIT {
RESET {
while (localvar_stack)
- poplocalvars();
+ poplocalvars(0);
}
#endif
@@ -339,24 +337,6 @@ intmax_t lookupvarint(const char *name)
/*
- * Search the environment of a builtin command.
- */
-
-char *
-bltinlookup(const char *name)
-{
- struct strlist *sp;
-
- for (sp = cmdenviron ; sp ; sp = sp->next) {
- if (varequal(sp->text, name))
- return strchrnul(sp->text, '=') + 1;
- }
- return lookupvar(name);
-}
-
-
-
-/*
* Generate a list of variables satisfying the given conditions.
*/
@@ -486,8 +466,7 @@ localcmd(int argc, char **argv)
* "-" as a special case.
*/
-STATIC void
-mklocal(char *name)
+void mklocal(char *name)
{
struct localvar *lvp;
struct var **vpp;
@@ -534,7 +513,7 @@ mklocal(char *name)
*/
void
-poplocalvars(void)
+poplocalvars(int keep)
{
struct localvar_list *ll;
struct localvar *lvp, *next;
@@ -551,7 +530,23 @@ poplocalvars(void)
next = lvp->next;
vp = lvp->vp;
TRACE(("poplocalvar %s", vp ? vp->text : "-"));
- if (vp == NULL) { /* $- saved */
+ if (keep) {
+ int bits = VSTRFIXED;
+
+ if (lvp->flags != VUNSET) {
+ if (vp->text == lvp->text)
+ bits |= VTEXTFIXED;
+ else if (!(lvp->flags & (VTEXTFIXED|VSTACK)))
+ ckfree(lvp->text);
+ }
+
+ vp->flags &= ~bits;
+ vp->flags |= (lvp->flags & bits);
+
+ if ((vp->flags &
+ (VEXPORT|VREADONLY|VSTRFIXED|VUNSET)) == VUNSET)
+ unsetvar(vp->text);
+ } else if (vp == NULL) { /* $- saved */
memcpy(optlist, lvp->text, sizeof(optlist));
ckfree(lvp->text);
optschanged();
diff --git a/usr/dash/var.h b/usr/dash/var.h
index 2bb82b1793b96..363f3055cbe0f 100644
--- a/usr/dash/var.h
+++ b/usr/dash/var.h
@@ -133,14 +133,14 @@ struct strlist;
void listsetvar(struct strlist *, int);
char *lookupvar(const char *);
intmax_t lookupvarint(const char *);
-char *bltinlookup(const char *);
char **listvars(int, int, char ***);
#define environment() listvars(VEXPORT, VUNSET, 0)
int showvars(const char *, int, int);
int exportcmd(int, char **);
int localcmd(int, char **);
+void mklocal(char *);
void pushlocalvars(void);
-void poplocalvars(void);
+void poplocalvars(int);
int unsetcmd(int, char **);
void unsetvar(const char *);
int varcmp(const char *, const char *);
@@ -148,3 +148,12 @@ int varcmp(const char *, const char *);
static inline int varequal(const char *a, const char *b) {
return !varcmp(a, b);
}
+
+/*
+ * Search the environment of a builtin command.
+ */
+
+static inline char *bltinlookup(const char *name)
+{
+ return lookupvar(name);
+}