diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-20 22:04:21 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-20 22:04:21 +0000 |
commit | ad4bd0548a5a9b630606ca95794cee8b31671c9a (patch) | |
tree | 41e681d086425d31f7ae0e0e36e94dff7bda40e0 | |
parent | d40fa397e45b35b62d1967a88036e06b4c061abe (diff) | |
download | busybox-w32-ad4bd0548a5a9b630606ca95794cee8b31671c9a.tar.gz busybox-w32-ad4bd0548a5a9b630606ca95794cee8b31671c9a.tar.bz2 busybox-w32-ad4bd0548a5a9b630606ca95794cee8b31671c9a.zip |
hush: export -n support
function old new delta
builtin_export 206 256 +50
set_local_var 248 265 +17
expand_variables 2204 2203 -1
-rw-r--r-- | shell/Config.in | 7 | ||||
-rw-r--r-- | shell/hush.c | 53 | ||||
-rw-r--r-- | shell/hush_test/hush-misc/export-n.right | 10 | ||||
-rwxr-xr-x | shell/hush_test/hush-misc/export-n.tests | 37 |
4 files changed, 95 insertions, 12 deletions
diff --git a/shell/Config.in b/shell/Config.in index 6cc11ce80..57969f02c 100644 --- a/shell/Config.in +++ b/shell/Config.in | |||
@@ -232,6 +232,13 @@ config HUSH_FUNCTIONS | |||
232 | help | 232 | help |
233 | Enable support for shell functions in hush. +800 bytes. | 233 | Enable support for shell functions in hush. +800 bytes. |
234 | 234 | ||
235 | config HUSH_EXPORT_N | ||
236 | bool "Support export '-n' option" | ||
237 | default n | ||
238 | depends on HUSH | ||
239 | help | ||
240 | Enable support for export '-n' option in hush. It is a bash extension. | ||
241 | |||
235 | config LASH | 242 | config LASH |
236 | bool "lash (deprecated: aliased to hush)" | 243 | bool "lash (deprecated: aliased to hush)" |
237 | default n | 244 | default n |
diff --git a/shell/hush.c b/shell/hush.c index d08652656..d59a5de82 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -1253,10 +1253,10 @@ static const char *get_local_var_value(const char *src) | |||
1253 | /* str holds "NAME=VAL" and is expected to be malloced. | 1253 | /* str holds "NAME=VAL" and is expected to be malloced. |
1254 | * We take ownership of it. | 1254 | * We take ownership of it. |
1255 | * flg_export: | 1255 | * flg_export: |
1256 | * 0: do not export | 1256 | * 0: do not change export flag |
1257 | * 1: export | 1257 | * (if creating new variable, flag will be 0) |
1258 | * -1: if NAME is set, leave export status alone | 1258 | * 1: set export flag and putenv the variable |
1259 | * if NAME is not set, do not export | 1259 | * -1: clear export flag and unsetenv the variable |
1260 | * flg_read_only is set only when we handle -R var=val | 1260 | * flg_read_only is set only when we handle -R var=val |
1261 | */ | 1261 | */ |
1262 | #if BB_MMU | 1262 | #if BB_MMU |
@@ -1297,6 +1297,7 @@ static int set_local_var(char *str, int flg_export, int flg_read_only) | |||
1297 | free(str); | 1297 | free(str); |
1298 | return -1; | 1298 | return -1; |
1299 | } | 1299 | } |
1300 | //TODO: optimize out redundant unsetenv/putenv's? | ||
1300 | debug_printf_env("%s: unsetenv '%s'\n", __func__, str); | 1301 | debug_printf_env("%s: unsetenv '%s'\n", __func__, str); |
1301 | unsetenv(str); /* just in case */ | 1302 | unsetenv(str); /* just in case */ |
1302 | *value = '='; | 1303 | *value = '='; |
@@ -1331,8 +1332,13 @@ static int set_local_var(char *str, int flg_export, int flg_read_only) | |||
1331 | if (flg_export == 1) | 1332 | if (flg_export == 1) |
1332 | cur->flg_export = 1; | 1333 | cur->flg_export = 1; |
1333 | if (cur->flg_export) { | 1334 | if (cur->flg_export) { |
1334 | debug_printf_env("%s: putenv '%s'\n", __func__, cur->varstr); | 1335 | if (flg_export == -1) { |
1335 | return putenv(cur->varstr); | 1336 | cur->flg_export = 0; |
1337 | /* unsetenv was already done */ | ||
1338 | } else { | ||
1339 | debug_printf_env("%s: putenv '%s'\n", __func__, cur->varstr); | ||
1340 | return putenv(cur->varstr); | ||
1341 | } | ||
1336 | } | 1342 | } |
1337 | return 0; | 1343 | return 0; |
1338 | } | 1344 | } |
@@ -2214,7 +2220,7 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask) | |||
2214 | val = NULL; | 2220 | val = NULL; |
2215 | } else { | 2221 | } else { |
2216 | char *new_var = xasprintf("%s=%s", var, val); | 2222 | char *new_var = xasprintf("%s=%s", var, val); |
2217 | set_local_var(new_var, -1, 0); | 2223 | set_local_var(new_var, 0, 0); |
2218 | } | 2224 | } |
2219 | } | 2225 | } |
2220 | } | 2226 | } |
@@ -6400,7 +6406,9 @@ static void print_escaped(const char *s) | |||
6400 | 6406 | ||
6401 | static int builtin_export(char **argv) | 6407 | static int builtin_export(char **argv) |
6402 | { | 6408 | { |
6403 | if (*++argv == NULL) { | 6409 | unsigned opt_unexport; |
6410 | |||
6411 | if (argv[1] == NULL) { | ||
6404 | char **e = environ; | 6412 | char **e = environ; |
6405 | if (e) { | 6413 | if (e) { |
6406 | while (*e) { | 6414 | while (*e) { |
@@ -6426,15 +6434,33 @@ static int builtin_export(char **argv) | |||
6426 | return EXIT_SUCCESS; | 6434 | return EXIT_SUCCESS; |
6427 | } | 6435 | } |
6428 | 6436 | ||
6437 | #if ENABLE_HUSH_EXPORT_N | ||
6438 | opt_unexport = getopt32(argv, "+n"); /* "+": stop at 1st non-option */ | ||
6439 | argv += optind; | ||
6440 | #else | ||
6441 | opt_unexport = 0; | ||
6442 | argv++; | ||
6443 | #endif | ||
6444 | |||
6429 | do { | 6445 | do { |
6430 | char *name = *argv; | 6446 | char *name = *argv; |
6431 | 6447 | ||
6432 | /* So far we do not check that name is valid */ | 6448 | /* So far we do not check that name is valid (TODO?) */ |
6449 | |||
6433 | if (strchr(name, '=') == NULL) { | 6450 | if (strchr(name, '=') == NULL) { |
6434 | /* Exporting a name without a =VALUE */ | ||
6435 | struct variable *var; | 6451 | struct variable *var; |
6436 | 6452 | ||
6437 | var = get_local_var(name); | 6453 | var = get_local_var(name); |
6454 | if (opt_unexport) { | ||
6455 | /* export -n NAME (without =VALUE) */ | ||
6456 | if (var) { | ||
6457 | var->flg_export = 0; | ||
6458 | debug_printf_env("%s: unsetenv '%s'\n", __func__, name); | ||
6459 | unsetenv(name); | ||
6460 | } /* else: export -n NOT_EXISTING_VAR: no-op */ | ||
6461 | continue; | ||
6462 | } | ||
6463 | /* export NAME (without =VALUE) */ | ||
6438 | if (var) { | 6464 | if (var) { |
6439 | var->flg_export = 1; | 6465 | var->flg_export = 1; |
6440 | debug_printf_env("%s: putenv '%s'\n", __func__, var->varstr); | 6466 | debug_printf_env("%s: putenv '%s'\n", __func__, var->varstr); |
@@ -6448,10 +6474,13 @@ static int builtin_export(char **argv) | |||
6448 | * We just set it to "" and export. */ | 6474 | * We just set it to "" and export. */ |
6449 | name = xasprintf("%s=", name); | 6475 | name = xasprintf("%s=", name); |
6450 | } else { | 6476 | } else { |
6451 | /* Exporting VAR=VALUE */ | 6477 | /* (Un)exporting NAME=VALUE */ |
6452 | name = xstrdup(name); | 6478 | name = xstrdup(name); |
6453 | } | 6479 | } |
6454 | set_local_var(name, 1, 0); | 6480 | set_local_var(name, |
6481 | /*export:*/ (opt_unexport ? -1 : 1), | ||
6482 | /*readonly:*/ 0 | ||
6483 | ); | ||
6455 | } while (*++argv); | 6484 | } while (*++argv); |
6456 | 6485 | ||
6457 | return EXIT_SUCCESS; | 6486 | return EXIT_SUCCESS; |
diff --git a/shell/hush_test/hush-misc/export-n.right b/shell/hush_test/hush-misc/export-n.right new file mode 100644 index 000000000..3d55bf752 --- /dev/null +++ b/shell/hush_test/hush-misc/export-n.right | |||
@@ -0,0 +1,10 @@ | |||
1 | export aaa1="'''" | ||
2 | export aaa2='' | ||
3 | export aaa3="'''"'abc' | ||
4 | export aaa8='8' | ||
5 | aaa9=9 | ||
6 | aaa10=10 | ||
7 | Nothing: | ||
8 | Nothing: | ||
9 | Nothing: | ||
10 | Done | ||
diff --git a/shell/hush_test/hush-misc/export-n.tests b/shell/hush_test/hush-misc/export-n.tests new file mode 100755 index 000000000..5252a1e14 --- /dev/null +++ b/shell/hush_test/hush-misc/export-n.tests | |||
@@ -0,0 +1,37 @@ | |||
1 | export aaa1="'''" | ||
2 | export aaa2="" | ||
3 | export aaa3="'''abc" | ||
4 | export | grep aaa.= | ||
5 | |||
6 | export -n aaa1 | ||
7 | unset aaa2; export -n aaa2="ghi" | ||
8 | export -n aaa3="klm" | ||
9 | export | grep aaa.= | ||
10 | |||
11 | export aaa4=4 aaa5=5 | ||
12 | export -n aaa4=4n | ||
13 | export -n aaa5 | ||
14 | export | grep aaa.= | ||
15 | |||
16 | export aaa5=5 aaa6=6 aaa7=7 aaa8=8 | ||
17 | export -n aaa5 aaa6=6n aaa7 | ||
18 | export | grep aaa.= | ||
19 | |||
20 | aaa9=9 | ||
21 | export -n aaa9 | ||
22 | set | grep ^aaa9= | ||
23 | |||
24 | export aaa10=10 | ||
25 | export -n aaa10 | ||
26 | set | grep ^aaa10= | ||
27 | |||
28 | |||
29 | export EXPORTED=qwe | ||
30 | export -nnnnnn nnnnnn; echo "Nothing:"; env | grep nnnnnn | ||
31 | |||
32 | export -n EXPORTED=123; echo "Nothing:"; env | grep ^EXPORTED | ||
33 | |||
34 | export EXPORTED=qwe | ||
35 | export -n EXPORTED; EXPORTED=123; echo "Nothing:"; env | grep ^EXPORTED | ||
36 | |||
37 | echo Done | ||