diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2010-05-25 20:55:05 +0800 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2010-05-26 16:00:20 +0800 |
commit | e3c9a7dd70976157cd7141ac8b25aa71f1eb6842 (patch) | |
tree | bfc2a6818e4a4687f666f2dc37753647c57021da | |
parent | [VAR] Fix poplocalvar leak (diff) | |
download | dash-e3c9a7dd70976157cd7141ac8b25aa71f1eb6842.tar.gz dash-e3c9a7dd70976157cd7141ac8b25aa71f1eb6842.zip |
[VAR] Move unsetvar functionality into setvareq
This patch moves the unsetvar code into setvareq so that we can no have a pathological case of an unset variable hanging around unless it has a bit pinning it like VEXPORT. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r-- | ChangeLog | 1 | ||||
-rw-r--r-- | src/var.c | 54 | ||||
-rw-r--r-- | src/var.h | 2 |
3 files changed, 19 insertions, 38 deletions
diff --git a/ChangeLog b/ChangeLog index f3c7701..1f7120f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ 2010-05-25 Herbert Xu <herbert@gondor.apana.org.au> * Fix poplocalvar leak. + * Move unsetvar functionality into setvareq. 2010-05-24 Herbert Xu <herbert@gondor.apana.org.au> diff --git a/src/var.c b/src/var.c index fc6d367..12f2f6c 100644 --- a/src/var.c +++ b/src/var.c @@ -266,10 +266,22 @@ setvareq(char *s, int flags) if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0) ckfree(vp->text); + if (((flags & (VEXPORT|VREADONLY|VSTRFIXED|VUNSET)) | + (vp->flags & VSTRFIXED)) == VUNSET) { + *vpp = vp->next; + ckfree(vp); +out_free: + if ((flags & (VTEXTFIXED|VSTACK|VNOSAVE)) == VNOSAVE) + ckfree(s); + return; + } + flags |= vp->flags & ~(VTEXTFIXED|VSTACK|VNOSAVE|VUNSET); } else { if (flags & VNOSET) return; + if ((flags & (VEXPORT|VREADONLY|VSTRFIXED|VUNSET)) == VUNSET) + goto out_free; /* not found */ vp = ckmalloc(sizeof (*vp)); vp->next = *vpp; @@ -588,7 +600,6 @@ unsetcmd(int argc, char **argv) char **ap; int i; int flag = 0; - int ret = 0; while ((i = nextopt("vf")) != '\0') { flag = i; @@ -596,15 +607,13 @@ unsetcmd(int argc, char **argv) for (ap = argptr; *ap ; ap++) { if (flag != 'f') { - i = unsetvar(*ap); - ret |= i; - if (!(i & 2)) - continue; + unsetvar(*ap); + continue; } if (flag != 'v') unsetfunc(*ap); } - return ret & 1; + return 0; } @@ -612,38 +621,9 @@ unsetcmd(int argc, char **argv) * Unset the specified variable. */ -int -unsetvar(const char *s) +void unsetvar(const char *s) { - struct var **vpp; - struct var *vp; - int retval; - - vpp = findvar(hashvar(s), s); - vp = *vpp; - retval = 2; - if (vp) { - int flags = vp->flags; - - retval = 1; - if (flags & VREADONLY) - goto out; - if ((flags & VSTRFIXED) == 0) { - INTOFF; - if ((flags & (VTEXTFIXED|VSTACK)) == 0) - ckfree(vp->text); - *vpp = vp->next; - ckfree(vp); - INTON; - } else if (!(flags & VUNSET)) { - setvar(s, 0, 0); - vp->flags &= ~VEXPORT; - } - retval = 0; - } - -out: - return retval; + setvar(s, 0, 0); } diff --git a/src/var.h b/src/var.h index 32b0dde..2bb82b1 100644 --- a/src/var.h +++ b/src/var.h @@ -142,7 +142,7 @@ int localcmd(int, char **); void pushlocalvars(void); void poplocalvars(void); int unsetcmd(int, char **); -int unsetvar(const char *); +void unsetvar(const char *); int varcmp(const char *, const char *); static inline int varequal(const char *a, const char *b) { |