hush: export -n support
function old new delta builtin_export 206 256 +50 set_local_var 248 265 +17 expand_variables 2204 2203 -1
This commit is contained in:
parent
d40fa397e4
commit
ad4bd0548a
@ -232,6 +232,13 @@ config HUSH_FUNCTIONS
|
|||||||
help
|
help
|
||||||
Enable support for shell functions in hush. +800 bytes.
|
Enable support for shell functions in hush. +800 bytes.
|
||||||
|
|
||||||
|
config HUSH_EXPORT_N
|
||||||
|
bool "Support export '-n' option"
|
||||||
|
default n
|
||||||
|
depends on HUSH
|
||||||
|
help
|
||||||
|
Enable support for export '-n' option in hush. It is a bash extension.
|
||||||
|
|
||||||
config LASH
|
config LASH
|
||||||
bool "lash (deprecated: aliased to hush)"
|
bool "lash (deprecated: aliased to hush)"
|
||||||
default n
|
default n
|
||||||
|
53
shell/hush.c
53
shell/hush.c
@ -1253,10 +1253,10 @@ static const char *get_local_var_value(const char *src)
|
|||||||
/* str holds "NAME=VAL" and is expected to be malloced.
|
/* str holds "NAME=VAL" and is expected to be malloced.
|
||||||
* We take ownership of it.
|
* We take ownership of it.
|
||||||
* flg_export:
|
* flg_export:
|
||||||
* 0: do not export
|
* 0: do not change export flag
|
||||||
* 1: export
|
* (if creating new variable, flag will be 0)
|
||||||
* -1: if NAME is set, leave export status alone
|
* 1: set export flag and putenv the variable
|
||||||
* if NAME is not set, do not export
|
* -1: clear export flag and unsetenv the variable
|
||||||
* flg_read_only is set only when we handle -R var=val
|
* flg_read_only is set only when we handle -R var=val
|
||||||
*/
|
*/
|
||||||
#if BB_MMU
|
#if BB_MMU
|
||||||
@ -1297,6 +1297,7 @@ static int set_local_var(char *str, int flg_export, int flg_read_only)
|
|||||||
free(str);
|
free(str);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
//TODO: optimize out redundant unsetenv/putenv's?
|
||||||
debug_printf_env("%s: unsetenv '%s'\n", __func__, str);
|
debug_printf_env("%s: unsetenv '%s'\n", __func__, str);
|
||||||
unsetenv(str); /* just in case */
|
unsetenv(str); /* just in case */
|
||||||
*value = '=';
|
*value = '=';
|
||||||
@ -1331,8 +1332,13 @@ static int set_local_var(char *str, int flg_export, int flg_read_only)
|
|||||||
if (flg_export == 1)
|
if (flg_export == 1)
|
||||||
cur->flg_export = 1;
|
cur->flg_export = 1;
|
||||||
if (cur->flg_export) {
|
if (cur->flg_export) {
|
||||||
debug_printf_env("%s: putenv '%s'\n", __func__, cur->varstr);
|
if (flg_export == -1) {
|
||||||
return putenv(cur->varstr);
|
cur->flg_export = 0;
|
||||||
|
/* unsetenv was already done */
|
||||||
|
} else {
|
||||||
|
debug_printf_env("%s: putenv '%s'\n", __func__, cur->varstr);
|
||||||
|
return putenv(cur->varstr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -2214,7 +2220,7 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask)
|
|||||||
val = NULL;
|
val = NULL;
|
||||||
} else {
|
} else {
|
||||||
char *new_var = xasprintf("%s=%s", var, val);
|
char *new_var = xasprintf("%s=%s", var, val);
|
||||||
set_local_var(new_var, -1, 0);
|
set_local_var(new_var, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6400,7 +6406,9 @@ static void print_escaped(const char *s)
|
|||||||
|
|
||||||
static int builtin_export(char **argv)
|
static int builtin_export(char **argv)
|
||||||
{
|
{
|
||||||
if (*++argv == NULL) {
|
unsigned opt_unexport;
|
||||||
|
|
||||||
|
if (argv[1] == NULL) {
|
||||||
char **e = environ;
|
char **e = environ;
|
||||||
if (e) {
|
if (e) {
|
||||||
while (*e) {
|
while (*e) {
|
||||||
@ -6426,15 +6434,33 @@ static int builtin_export(char **argv)
|
|||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ENABLE_HUSH_EXPORT_N
|
||||||
|
opt_unexport = getopt32(argv, "+n"); /* "+": stop at 1st non-option */
|
||||||
|
argv += optind;
|
||||||
|
#else
|
||||||
|
opt_unexport = 0;
|
||||||
|
argv++;
|
||||||
|
#endif
|
||||||
|
|
||||||
do {
|
do {
|
||||||
char *name = *argv;
|
char *name = *argv;
|
||||||
|
|
||||||
/* So far we do not check that name is valid */
|
/* So far we do not check that name is valid (TODO?) */
|
||||||
|
|
||||||
if (strchr(name, '=') == NULL) {
|
if (strchr(name, '=') == NULL) {
|
||||||
/* Exporting a name without a =VALUE */
|
|
||||||
struct variable *var;
|
struct variable *var;
|
||||||
|
|
||||||
var = get_local_var(name);
|
var = get_local_var(name);
|
||||||
|
if (opt_unexport) {
|
||||||
|
/* export -n NAME (without =VALUE) */
|
||||||
|
if (var) {
|
||||||
|
var->flg_export = 0;
|
||||||
|
debug_printf_env("%s: unsetenv '%s'\n", __func__, name);
|
||||||
|
unsetenv(name);
|
||||||
|
} /* else: export -n NOT_EXISTING_VAR: no-op */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* export NAME (without =VALUE) */
|
||||||
if (var) {
|
if (var) {
|
||||||
var->flg_export = 1;
|
var->flg_export = 1;
|
||||||
debug_printf_env("%s: putenv '%s'\n", __func__, var->varstr);
|
debug_printf_env("%s: putenv '%s'\n", __func__, var->varstr);
|
||||||
@ -6448,10 +6474,13 @@ static int builtin_export(char **argv)
|
|||||||
* We just set it to "" and export. */
|
* We just set it to "" and export. */
|
||||||
name = xasprintf("%s=", name);
|
name = xasprintf("%s=", name);
|
||||||
} else {
|
} else {
|
||||||
/* Exporting VAR=VALUE */
|
/* (Un)exporting NAME=VALUE */
|
||||||
name = xstrdup(name);
|
name = xstrdup(name);
|
||||||
}
|
}
|
||||||
set_local_var(name, 1, 0);
|
set_local_var(name,
|
||||||
|
/*export:*/ (opt_unexport ? -1 : 1),
|
||||||
|
/*readonly:*/ 0
|
||||||
|
);
|
||||||
} while (*++argv);
|
} while (*++argv);
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
10
shell/hush_test/hush-misc/export-n.right
Normal file
10
shell/hush_test/hush-misc/export-n.right
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
export aaa1="'''"
|
||||||
|
export aaa2=''
|
||||||
|
export aaa3="'''"'abc'
|
||||||
|
export aaa8='8'
|
||||||
|
aaa9=9
|
||||||
|
aaa10=10
|
||||||
|
Nothing:
|
||||||
|
Nothing:
|
||||||
|
Nothing:
|
||||||
|
Done
|
37
shell/hush_test/hush-misc/export-n.tests
Executable file
37
shell/hush_test/hush-misc/export-n.tests
Executable file
@ -0,0 +1,37 @@
|
|||||||
|
export aaa1="'''"
|
||||||
|
export aaa2=""
|
||||||
|
export aaa3="'''abc"
|
||||||
|
export | grep aaa.=
|
||||||
|
|
||||||
|
export -n aaa1
|
||||||
|
unset aaa2; export -n aaa2="ghi"
|
||||||
|
export -n aaa3="klm"
|
||||||
|
export | grep aaa.=
|
||||||
|
|
||||||
|
export aaa4=4 aaa5=5
|
||||||
|
export -n aaa4=4n
|
||||||
|
export -n aaa5
|
||||||
|
export | grep aaa.=
|
||||||
|
|
||||||
|
export aaa5=5 aaa6=6 aaa7=7 aaa8=8
|
||||||
|
export -n aaa5 aaa6=6n aaa7
|
||||||
|
export | grep aaa.=
|
||||||
|
|
||||||
|
aaa9=9
|
||||||
|
export -n aaa9
|
||||||
|
set | grep ^aaa9=
|
||||||
|
|
||||||
|
export aaa10=10
|
||||||
|
export -n aaa10
|
||||||
|
set | grep ^aaa10=
|
||||||
|
|
||||||
|
|
||||||
|
export EXPORTED=qwe
|
||||||
|
export -nnnnnn nnnnnn; echo "Nothing:"; env | grep nnnnnn
|
||||||
|
|
||||||
|
export -n EXPORTED=123; echo "Nothing:"; env | grep ^EXPORTED
|
||||||
|
|
||||||
|
export EXPORTED=qwe
|
||||||
|
export -n EXPORTED; EXPORTED=123; echo "Nothing:"; env | grep ^EXPORTED
|
||||||
|
|
||||||
|
echo Done
|
Loading…
Reference in New Issue
Block a user