aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-07-25 16:29:36 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2017-07-25 16:29:36 +0200
commitb28d4c3462e6b0e66322503f5ef0b941e0bb9cb8 (patch)
treed25bf78558574cdd8de6b802cf6486f66dfc6db9
parentbe669fa1fdff6f751c8cdd3fc18a9fa7a7f46cd3 (diff)
downloadbusybox-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.c57
-rw-r--r--shell/ash_test/ash-vars/readonly0.right2
-rw-r--r--shell/ash_test/ash-vars/unset.right17
-rwxr-xr-xshell/ash_test/ash-vars/unset.tests40
-rw-r--r--shell/hush_test/hush-vars/unset.right4
-rwxr-xr-xshell/hush_test/hush-vars/unset.tests7
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 */
2334static int 2345static void
2335unsetvar(const char *s) 2346unsetvar(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
13240static const unsigned char timescmd_str[] ALIGN1 = { 13215static 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
11Fail:2 11Fail:2
12 12
13Fail: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
22
3./unset.tests: unset: line 5: illegal option -m
42
50
6___
70 f g
80 g
90
10___
110 f g
120
130 f g
140
15___
16./unset.tests: unset: line 36: VAR_RO: is read only
172 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 -)
4echo $?
5(unset -m a b c)
6echo $?
7
8# check funky usage
9unset
10echo $?
11
12# check normal usage
13echo ___
14f=f g=g
15echo $? $f $g
16unset f
17echo $? $f $g
18unset g
19echo $? $f $g
20
21echo ___
22f=f g=g
23echo $? $f $g
24unset f g
25echo $? $f $g
26f=f g=g
27echo $? $f $g
28unset -v f g
29echo $? $f $g
30
31# check read only vars
32echo ___
33f=f g=g
34VAR_RO=1
35readonly VAR_RO
36(unset VAR_RO)
37echo $? $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 @@ ___
120 f g 120 f g
130 130
14___ 14___
15hush: HUSH_VERSION: readonly variable 15hush: VAR_RO: readonly variable
161 f g 161 f g
17hush: HUSH_VERSION: readonly variable 17hush: VAR_RO: readonly variable
181 181
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
2unset - 3unset -
3echo $? 4echo $?
4unset -m a b c 5unset -m a b c
@@ -30,7 +31,9 @@ echo $? $f $g
30# check read only vars 31# check read only vars
31echo ___ 32echo ___
32f=f g=g 33f=f g=g
33unset HUSH_VERSION 34VAR_RO=1
35readonly VAR_RO
36unset VAR_RO
34echo $? $f $g 37echo $? $f $g
35unset f HUSH_VERSION g 38unset f VAR_RO g
36echo $? $f $g 39echo $? $f $g