ash: [VAR] Move unsetvar functionality into setvareq
Upstream commit: Date: Tue, 25 May 2010 20:55:05 +0800 [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> function old new delta setvareq 227 303 +76 expmeta 517 521 +4 localcmd 364 366 +2 unsetcmd 96 76 -20 unsetvar 129 7 -122 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 3/2 up/down: 82/-142) Total: -60 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
be669fa1fd
commit
b28d4c3462
57
shell/ash.c
57
shell/ash.c
@ -2269,11 +2269,22 @@ setvareq(char *s, int flags)
|
||||
if (!(vp->flags & (VTEXTFIXED|VSTACK)))
|
||||
free((char*)vp->var_text);
|
||||
|
||||
if (((flags & (VEXPORT|VREADONLY|VSTRFIXED|VUNSET)) | (vp->flags & VSTRFIXED)) == VUNSET) {
|
||||
*vpp = vp->next;
|
||||
free(vp);
|
||||
out_free:
|
||||
if ((flags & (VTEXTFIXED|VSTACK|VNOSAVE)) == VNOSAVE)
|
||||
free(s);
|
||||
return;
|
||||
}
|
||||
|
||||
flags |= vp->flags & ~(VTEXTFIXED|VSTACK|VNOSAVE|VUNSET);
|
||||
} else {
|
||||
/* variable s is not found */
|
||||
if (flags & VNOSET)
|
||||
return;
|
||||
if ((flags & (VEXPORT|VREADONLY|VSTRFIXED|VUNSET)) == VUNSET)
|
||||
goto out_free;
|
||||
vp = ckzalloc(sizeof(*vp));
|
||||
vp->next = *vpp;
|
||||
/*vp->func = NULL; - ckzalloc did it */
|
||||
@ -2331,43 +2342,10 @@ setvar0(const char *name, const char *val)
|
||||
/*
|
||||
* Unset the specified variable.
|
||||
*/
|
||||
static int
|
||||
static 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 ENABLE_ASH_RANDOM_SUPPORT
|
||||
vp->flags &= ~VDYNAMIC;
|
||||
#endif
|
||||
if (flags & VUNSET)
|
||||
goto ok;
|
||||
if ((flags & VSTRFIXED) == 0) {
|
||||
INT_OFF;
|
||||
if ((flags & (VTEXTFIXED|VSTACK)) == 0)
|
||||
free((char*)vp->var_text);
|
||||
*vpp = vp->next;
|
||||
free(vp);
|
||||
INT_ON;
|
||||
} else {
|
||||
setvar0(s, NULL);
|
||||
vp->flags &= ~VEXPORT;
|
||||
}
|
||||
ok:
|
||||
retval = 0;
|
||||
}
|
||||
out:
|
||||
return retval;
|
||||
setvar0(s, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -13218,7 +13196,6 @@ unsetcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
|
||||
char **ap;
|
||||
int i;
|
||||
int flag = 0;
|
||||
int ret = 0;
|
||||
|
||||
while ((i = nextopt("vf")) != 0) {
|
||||
flag = i;
|
||||
@ -13226,15 +13203,13 @@ unsetcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static const unsigned char timescmd_str[] ALIGN1 = {
|
||||
|
@ -10,4 +10,4 @@ Fail:2
|
||||
./readonly0.tests: export: line 27: a: is read only
|
||||
Fail:2
|
||||
|
||||
Fail:1
|
||||
./readonly0.tests: unset: line 44: a: is read only
|
||||
|
17
shell/ash_test/ash-vars/unset.right
Normal file
17
shell/ash_test/ash-vars/unset.right
Normal file
@ -0,0 +1,17 @@
|
||||
./unset.tests: unset: line 3: -: bad variable name
|
||||
2
|
||||
./unset.tests: unset: line 5: illegal option -m
|
||||
2
|
||||
0
|
||||
___
|
||||
0 f g
|
||||
0 g
|
||||
0
|
||||
___
|
||||
0 f g
|
||||
0
|
||||
0 f g
|
||||
0
|
||||
___
|
||||
./unset.tests: unset: line 36: VAR_RO: is read only
|
||||
2 f g
|
40
shell/ash_test/ash-vars/unset.tests
Executable file
40
shell/ash_test/ash-vars/unset.tests
Executable file
@ -0,0 +1,40 @@
|
||||
# check invalid options are rejected
|
||||
# bash: in posix mode, aborts if non-interactive; using subshell to avoid that
|
||||
(unset -)
|
||||
echo $?
|
||||
(unset -m a b c)
|
||||
echo $?
|
||||
|
||||
# check funky usage
|
||||
unset
|
||||
echo $?
|
||||
|
||||
# check normal usage
|
||||
echo ___
|
||||
f=f g=g
|
||||
echo $? $f $g
|
||||
unset f
|
||||
echo $? $f $g
|
||||
unset g
|
||||
echo $? $f $g
|
||||
|
||||
echo ___
|
||||
f=f g=g
|
||||
echo $? $f $g
|
||||
unset f g
|
||||
echo $? $f $g
|
||||
f=f g=g
|
||||
echo $? $f $g
|
||||
unset -v f g
|
||||
echo $? $f $g
|
||||
|
||||
# check read only vars
|
||||
echo ___
|
||||
f=f g=g
|
||||
VAR_RO=1
|
||||
readonly VAR_RO
|
||||
(unset VAR_RO)
|
||||
echo $? $f $g
|
||||
# not testing "do variables survive error halfway through unset" since unset aborts
|
||||
# unset f VAR_RO g
|
||||
#echo $? $f $g
|
@ -12,7 +12,7 @@ ___
|
||||
0 f g
|
||||
0
|
||||
___
|
||||
hush: HUSH_VERSION: readonly variable
|
||||
hush: VAR_RO: readonly variable
|
||||
1 f g
|
||||
hush: HUSH_VERSION: readonly variable
|
||||
hush: VAR_RO: readonly variable
|
||||
1
|
||||
|
@ -1,4 +1,5 @@
|
||||
# check invalid options are rejected
|
||||
# bash: in posix mode, aborts if non-interactive
|
||||
unset -
|
||||
echo $?
|
||||
unset -m a b c
|
||||
@ -30,7 +31,9 @@ echo $? $f $g
|
||||
# check read only vars
|
||||
echo ___
|
||||
f=f g=g
|
||||
unset HUSH_VERSION
|
||||
VAR_RO=1
|
||||
readonly VAR_RO
|
||||
unset VAR_RO
|
||||
echo $? $f $g
|
||||
unset f HUSH_VERSION g
|
||||
unset f VAR_RO g
|
||||
echo $? $f $g
|
||||
|
Loading…
Reference in New Issue
Block a user