diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-07-25 16:29:36 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-07-25 16:29:36 +0200 |
commit | b28d4c3462e6b0e66322503f5ef0b941e0bb9cb8 (patch) | |
tree | d25bf78558574cdd8de6b802cf6486f66dfc6db9 | |
parent | be669fa1fdff6f751c8cdd3fc18a9fa7a7f46cd3 (diff) | |
download | busybox-w32-b28d4c3462e6b0e66322503f5ef0b941e0bb9cb8.tar.gz busybox-w32-b28d4c3462e6b0e66322503f5ef0b941e0bb9cb8.tar.bz2 busybox-w32-b28d4c3462e6b0e66322503f5ef0b941e0bb9cb8.zip |
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>
-rw-r--r-- | shell/ash.c | 57 | ||||
-rw-r--r-- | shell/ash_test/ash-vars/readonly0.right | 2 | ||||
-rw-r--r-- | shell/ash_test/ash-vars/unset.right | 17 | ||||
-rwxr-xr-x | shell/ash_test/ash-vars/unset.tests | 40 | ||||
-rw-r--r-- | shell/hush_test/hush-vars/unset.right | 4 | ||||
-rwxr-xr-x | shell/hush_test/hush-vars/unset.tests | 7 |
6 files changed, 81 insertions, 46 deletions
diff --git a/shell/ash.c b/shell/ash.c index 0ae086e98..72ceba782 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -2269,11 +2269,22 @@ setvareq(char *s, int flags) | |||
2269 | if (!(vp->flags & (VTEXTFIXED|VSTACK))) | 2269 | if (!(vp->flags & (VTEXTFIXED|VSTACK))) |
2270 | free((char*)vp->var_text); | 2270 | free((char*)vp->var_text); |
2271 | 2271 | ||
2272 | if (((flags & (VEXPORT|VREADONLY|VSTRFIXED|VUNSET)) | (vp->flags & VSTRFIXED)) == VUNSET) { | ||
2273 | *vpp = vp->next; | ||
2274 | free(vp); | ||
2275 | out_free: | ||
2276 | if ((flags & (VTEXTFIXED|VSTACK|VNOSAVE)) == VNOSAVE) | ||
2277 | free(s); | ||
2278 | return; | ||
2279 | } | ||
2280 | |||
2272 | flags |= vp->flags & ~(VTEXTFIXED|VSTACK|VNOSAVE|VUNSET); | 2281 | flags |= vp->flags & ~(VTEXTFIXED|VSTACK|VNOSAVE|VUNSET); |
2273 | } else { | 2282 | } else { |
2274 | /* variable s is not found */ | 2283 | /* variable s is not found */ |
2275 | if (flags & VNOSET) | 2284 | if (flags & VNOSET) |
2276 | return; | 2285 | return; |
2286 | if ((flags & (VEXPORT|VREADONLY|VSTRFIXED|VUNSET)) == VUNSET) | ||
2287 | goto out_free; | ||
2277 | vp = ckzalloc(sizeof(*vp)); | 2288 | vp = ckzalloc(sizeof(*vp)); |
2278 | vp->next = *vpp; | 2289 | vp->next = *vpp; |
2279 | /*vp->func = NULL; - ckzalloc did it */ | 2290 | /*vp->func = NULL; - ckzalloc did it */ |
@@ -2331,43 +2342,10 @@ setvar0(const char *name, const char *val) | |||
2331 | /* | 2342 | /* |
2332 | * Unset the specified variable. | 2343 | * Unset the specified variable. |
2333 | */ | 2344 | */ |
2334 | static int | 2345 | static void |
2335 | unsetvar(const char *s) | 2346 | unsetvar(const char *s) |
2336 | { | 2347 | { |
2337 | struct var **vpp; | 2348 | setvar0(s, NULL); |
2338 | struct var *vp; | ||
2339 | int retval; | ||
2340 | |||
2341 | vpp = findvar(hashvar(s), s); | ||
2342 | vp = *vpp; | ||
2343 | retval = 2; | ||
2344 | if (vp) { | ||
2345 | int flags = vp->flags; | ||
2346 | |||
2347 | retval = 1; | ||
2348 | if (flags & VREADONLY) | ||
2349 | goto out; | ||
2350 | #if ENABLE_ASH_RANDOM_SUPPORT | ||
2351 | vp->flags &= ~VDYNAMIC; | ||
2352 | #endif | ||
2353 | if (flags & VUNSET) | ||
2354 | goto ok; | ||
2355 | if ((flags & VSTRFIXED) == 0) { | ||
2356 | INT_OFF; | ||
2357 | if ((flags & (VTEXTFIXED|VSTACK)) == 0) | ||
2358 | free((char*)vp->var_text); | ||
2359 | *vpp = vp->next; | ||
2360 | free(vp); | ||
2361 | INT_ON; | ||
2362 | } else { | ||
2363 | setvar0(s, NULL); | ||
2364 | vp->flags &= ~VEXPORT; | ||
2365 | } | ||
2366 | ok: | ||
2367 | retval = 0; | ||
2368 | } | ||
2369 | out: | ||
2370 | return retval; | ||
2371 | } | 2349 | } |
2372 | 2350 | ||
2373 | /* | 2351 | /* |
@@ -13218,7 +13196,6 @@ unsetcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
13218 | char **ap; | 13196 | char **ap; |
13219 | int i; | 13197 | int i; |
13220 | int flag = 0; | 13198 | int flag = 0; |
13221 | int ret = 0; | ||
13222 | 13199 | ||
13223 | while ((i = nextopt("vf")) != 0) { | 13200 | while ((i = nextopt("vf")) != 0) { |
13224 | flag = i; | 13201 | flag = i; |
@@ -13226,15 +13203,13 @@ unsetcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
13226 | 13203 | ||
13227 | for (ap = argptr; *ap; ap++) { | 13204 | for (ap = argptr; *ap; ap++) { |
13228 | if (flag != 'f') { | 13205 | if (flag != 'f') { |
13229 | i = unsetvar(*ap); | 13206 | unsetvar(*ap); |
13230 | ret |= i; | 13207 | continue; |
13231 | if (!(i & 2)) | ||
13232 | continue; | ||
13233 | } | 13208 | } |
13234 | if (flag != 'v') | 13209 | if (flag != 'v') |
13235 | unsetfunc(*ap); | 13210 | unsetfunc(*ap); |
13236 | } | 13211 | } |
13237 | return ret & 1; | 13212 | return 0; |
13238 | } | 13213 | } |
13239 | 13214 | ||
13240 | static const unsigned char timescmd_str[] ALIGN1 = { | 13215 | static const unsigned char timescmd_str[] ALIGN1 = { |
diff --git a/shell/ash_test/ash-vars/readonly0.right b/shell/ash_test/ash-vars/readonly0.right index f3a6bde9e..ecc4054f8 100644 --- a/shell/ash_test/ash-vars/readonly0.right +++ b/shell/ash_test/ash-vars/readonly0.right | |||
@@ -10,4 +10,4 @@ Fail:2 | |||
10 | ./readonly0.tests: export: line 27: a: is read only | 10 | ./readonly0.tests: export: line 27: a: is read only |
11 | Fail:2 | 11 | Fail:2 |
12 | 12 | ||
13 | Fail:1 | 13 | ./readonly0.tests: unset: line 44: a: is read only |
diff --git a/shell/ash_test/ash-vars/unset.right b/shell/ash_test/ash-vars/unset.right new file mode 100644 index 000000000..77d5abe9e --- /dev/null +++ b/shell/ash_test/ash-vars/unset.right | |||
@@ -0,0 +1,17 @@ | |||
1 | ./unset.tests: unset: line 3: -: bad variable name | ||
2 | 2 | ||
3 | ./unset.tests: unset: line 5: illegal option -m | ||
4 | 2 | ||
5 | 0 | ||
6 | ___ | ||
7 | 0 f g | ||
8 | 0 g | ||
9 | 0 | ||
10 | ___ | ||
11 | 0 f g | ||
12 | 0 | ||
13 | 0 f g | ||
14 | 0 | ||
15 | ___ | ||
16 | ./unset.tests: unset: line 36: VAR_RO: is read only | ||
17 | 2 f g | ||
diff --git a/shell/ash_test/ash-vars/unset.tests b/shell/ash_test/ash-vars/unset.tests new file mode 100755 index 000000000..11b392744 --- /dev/null +++ b/shell/ash_test/ash-vars/unset.tests | |||
@@ -0,0 +1,40 @@ | |||
1 | # check invalid options are rejected | ||
2 | # bash: in posix mode, aborts if non-interactive; using subshell to avoid that | ||
3 | (unset -) | ||
4 | echo $? | ||
5 | (unset -m a b c) | ||
6 | echo $? | ||
7 | |||
8 | # check funky usage | ||
9 | unset | ||
10 | echo $? | ||
11 | |||
12 | # check normal usage | ||
13 | echo ___ | ||
14 | f=f g=g | ||
15 | echo $? $f $g | ||
16 | unset f | ||
17 | echo $? $f $g | ||
18 | unset g | ||
19 | echo $? $f $g | ||
20 | |||
21 | echo ___ | ||
22 | f=f g=g | ||
23 | echo $? $f $g | ||
24 | unset f g | ||
25 | echo $? $f $g | ||
26 | f=f g=g | ||
27 | echo $? $f $g | ||
28 | unset -v f g | ||
29 | echo $? $f $g | ||
30 | |||
31 | # check read only vars | ||
32 | echo ___ | ||
33 | f=f g=g | ||
34 | VAR_RO=1 | ||
35 | readonly VAR_RO | ||
36 | (unset VAR_RO) | ||
37 | echo $? $f $g | ||
38 | # not testing "do variables survive error halfway through unset" since unset aborts | ||
39 | # unset f VAR_RO g | ||
40 | #echo $? $f $g | ||
diff --git a/shell/hush_test/hush-vars/unset.right b/shell/hush_test/hush-vars/unset.right index 1fbe76a73..097274201 100644 --- a/shell/hush_test/hush-vars/unset.right +++ b/shell/hush_test/hush-vars/unset.right | |||
@@ -12,7 +12,7 @@ ___ | |||
12 | 0 f g | 12 | 0 f g |
13 | 0 | 13 | 0 |
14 | ___ | 14 | ___ |
15 | hush: HUSH_VERSION: readonly variable | 15 | hush: VAR_RO: readonly variable |
16 | 1 f g | 16 | 1 f g |
17 | hush: HUSH_VERSION: readonly variable | 17 | hush: VAR_RO: readonly variable |
18 | 1 | 18 | 1 |
diff --git a/shell/hush_test/hush-vars/unset.tests b/shell/hush_test/hush-vars/unset.tests index f59ce5923..81243fbf9 100755 --- a/shell/hush_test/hush-vars/unset.tests +++ b/shell/hush_test/hush-vars/unset.tests | |||
@@ -1,4 +1,5 @@ | |||
1 | # check invalid options are rejected | 1 | # check invalid options are rejected |
2 | # bash: in posix mode, aborts if non-interactive | ||
2 | unset - | 3 | unset - |
3 | echo $? | 4 | echo $? |
4 | unset -m a b c | 5 | unset -m a b c |
@@ -30,7 +31,9 @@ echo $? $f $g | |||
30 | # check read only vars | 31 | # check read only vars |
31 | echo ___ | 32 | echo ___ |
32 | f=f g=g | 33 | f=f g=g |
33 | unset HUSH_VERSION | 34 | VAR_RO=1 |
35 | readonly VAR_RO | ||
36 | unset VAR_RO | ||
34 | echo $? $f $g | 37 | echo $? $f $g |
35 | unset f HUSH_VERSION g | 38 | unset f VAR_RO g |
36 | echo $? $f $g | 39 | echo $? $f $g |