diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2025-08-17 04:07:42 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2025-08-17 04:07:42 +0200 |
| commit | 94cb769b656d3e163533b95c1feedc5385662d46 (patch) | |
| tree | c7758b68dc44ea818e72656523a9ce19f17a317a /shell | |
| parent | 7423bbbe98dae5300f49ed45ffd42f44103b2078 (diff) | |
| download | busybox-w32-94cb769b656d3e163533b95c1feedc5385662d46.tar.gz busybox-w32-94cb769b656d3e163533b95c1feedc5385662d46.tar.bz2 busybox-w32-94cb769b656d3e163533b95c1feedc5385662d46.zip | |
hush: make "alias" print aliases in properly escaped form
function old new delta
print_pfx_escaped_nl - 83 +83
builtin_alias 216 218 +2
.rodata 105985 105975 -10
parse_stream 2873 2857 -16
builtin_set 301 259 -42
builtin_readonly 107 59 -48
builtin_export 145 93 -52
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/5 up/down: 85/-168) Total: -83 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/hush.c | 52 |
1 files changed, 21 insertions, 31 deletions
diff --git a/shell/hush.c b/shell/hush.c index 1c1333eb1..e3903a074 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
| @@ -11686,7 +11686,7 @@ static int FAST_FUNC builtin_umask(char **argv) | |||
| 11686 | } | 11686 | } |
| 11687 | #endif | 11687 | #endif |
| 11688 | 11688 | ||
| 11689 | #if ENABLE_HUSH_EXPORT || ENABLE_HUSH_READONLY || ENABLE_HUSH_SET || ENABLE_HUSH_TRAP | 11689 | #if ENABLE_HUSH_EXPORT || ENABLE_HUSH_READONLY || ENABLE_HUSH_SET || ENABLE_HUSH_TRAP || ENABLE_HUSH_ALIAS |
| 11690 | static void print_escaped(const char *s) | 11690 | static void print_escaped(const char *s) |
| 11691 | { | 11691 | { |
| 11692 | //TODO? bash "set" does not quote variables which contain only alnums and "%+,-./:=@_~", | 11692 | //TODO? bash "set" does not quote variables which contain only alnums and "%+,-./:=@_~", |
| @@ -11711,6 +11711,18 @@ static void print_escaped(const char *s) | |||
| 11711 | putchar('"'); | 11711 | putchar('"'); |
| 11712 | } while (*s); | 11712 | } while (*s); |
| 11713 | } | 11713 | } |
| 11714 | static void print_pfx_escaped_nl(const char *pfx, const char *s) | ||
| 11715 | { | ||
| 11716 | const char *p = strchr(s, '='); | ||
| 11717 | if (p) { | ||
| 11718 | if (pfx) | ||
| 11719 | printf("%s %.*s", pfx, (int)(p - s) + 1, s); | ||
| 11720 | else | ||
| 11721 | printf("%.*s", (int)(p - s) + 1, s); | ||
| 11722 | print_escaped(p + 1); | ||
| 11723 | putchar('\n'); | ||
| 11724 | } | ||
| 11725 | } | ||
| 11714 | #endif | 11726 | #endif |
| 11715 | 11727 | ||
| 11716 | #if ENABLE_HUSH_EXPORT || ENABLE_HUSH_LOCAL || ENABLE_HUSH_READONLY | 11728 | #if ENABLE_HUSH_EXPORT || ENABLE_HUSH_LOCAL || ENABLE_HUSH_READONLY |
| @@ -11821,14 +11833,7 @@ static int FAST_FUNC builtin_export(char **argv) | |||
| 11821 | * bash: declare -x VAR="VAL" | 11833 | * bash: declare -x VAR="VAL" |
| 11822 | * we follow ash example */ | 11834 | * we follow ash example */ |
| 11823 | const char *s = *e++; | 11835 | const char *s = *e++; |
| 11824 | const char *p = strchr(s, '='); | 11836 | print_pfx_escaped_nl("export", s); |
| 11825 | |||
| 11826 | if (!p) /* wtf? take next variable */ | ||
| 11827 | continue; | ||
| 11828 | /* "export VAR=" */ | ||
| 11829 | printf("%s %.*s", "export", (int)(p - s) + 1, s); | ||
| 11830 | print_escaped(p + 1); | ||
| 11831 | putchar('\n'); | ||
| 11832 | # endif | 11837 | # endif |
| 11833 | } | 11838 | } |
| 11834 | /*fflush_all(); - done after each builtin anyway */ | 11839 | /*fflush_all(); - done after each builtin anyway */ |
| @@ -11870,15 +11875,7 @@ static int FAST_FUNC builtin_readonly(char **argv) | |||
| 11870 | struct variable *e; | 11875 | struct variable *e; |
| 11871 | for (e = G.top_var; e; e = e->next) { | 11876 | for (e = G.top_var; e; e = e->next) { |
| 11872 | if (e->flg_read_only) { | 11877 | if (e->flg_read_only) { |
| 11873 | const char *s = e->varstr; | 11878 | print_pfx_escaped_nl("readonly", e->varstr); |
| 11874 | const char *p = strchr(s, '='); | ||
| 11875 | |||
| 11876 | if (!p) /* wtf? take next variable */ | ||
| 11877 | continue; | ||
| 11878 | /* "readonly VAR=" */ | ||
| 11879 | printf("%s %.*s", "readonly", (int)(p - s) + 1, s); | ||
| 11880 | print_escaped(p + 1); | ||
| 11881 | putchar('\n'); | ||
| 11882 | } | 11879 | } |
| 11883 | } | 11880 | } |
| 11884 | return EXIT_SUCCESS; | 11881 | return EXIT_SUCCESS; |
| @@ -11957,15 +11954,7 @@ static int FAST_FUNC builtin_set(char **argv) | |||
| 11957 | if (arg == NULL) { | 11954 | if (arg == NULL) { |
| 11958 | struct variable *e; | 11955 | struct variable *e; |
| 11959 | for (e = G.top_var; e; e = e->next) { | 11956 | for (e = G.top_var; e; e = e->next) { |
| 11960 | const char *s = e->varstr; | 11957 | print_pfx_escaped_nl(NULL, e->varstr); |
| 11961 | const char *p = strchr(s, '='); | ||
| 11962 | |||
| 11963 | if (!p) /* wtf? take next variable */ | ||
| 11964 | continue; | ||
| 11965 | /* var= */ | ||
| 11966 | printf("%.*s", (int)(p - s) + 1, s); | ||
| 11967 | print_escaped(p + 1); | ||
| 11968 | putchar('\n'); | ||
| 11969 | } | 11958 | } |
| 11970 | return EXIT_SUCCESS; | 11959 | return EXIT_SUCCESS; |
| 11971 | } | 11960 | } |
| @@ -12868,8 +12857,7 @@ static int FAST_FUNC builtin_alias(char **argv) | |||
| 12868 | if (!argv[1]) { | 12857 | if (!argv[1]) { |
| 12869 | alias = G.top_alias; | 12858 | alias = G.top_alias; |
| 12870 | while (alias) { | 12859 | while (alias) { |
| 12871 | //todo: use NAME='VALUE' format, not NAME=VALUE | 12860 | print_pfx_escaped_nl("alias", alias->str); |
| 12872 | printf("alias %s\n", alias->str); | ||
| 12873 | alias = alias->next; | 12861 | alias = alias->next; |
| 12874 | } | 12862 | } |
| 12875 | return 0; | 12863 | return 0; |
| @@ -12880,20 +12868,22 @@ static int FAST_FUNC builtin_alias(char **argv) | |||
| 12880 | * metacharacters or quoting characters | 12868 | * metacharacters or quoting characters |
| 12881 | * may not appear in an alias name */ | 12869 | * may not appear in an alias name */ |
| 12882 | char *eq = end_of_alias_name(*argv); | 12870 | char *eq = end_of_alias_name(*argv); |
| 12883 | if (*eq == '=') { | 12871 | if (*eq == '=' && eq != *argv) { |
| 12884 | /* alias NAME=VALUE */ | 12872 | /* alias NAME=VALUE */ |
| 12885 | new_alias(*argv, eq); | 12873 | new_alias(*argv, eq); |
| 12886 | } else { | 12874 | } else { |
| 12887 | eq = strchrnul(eq, '='); | 12875 | eq = strchrnul(eq, '='); |
| 12888 | if (*eq == '=') { | 12876 | if (*eq == '=') { |
| 12877 | /* alias 'NA&ME=VALUE' (invalid chars in name) */ | ||
| 12889 | bb_error_msg("alias: '%.*s': invalid alias name", (int)(eq - *argv), *argv); | 12878 | bb_error_msg("alias: '%.*s': invalid alias name", (int)(eq - *argv), *argv); |
| 12890 | continue; /* continue processing argv (bash compat) */ | 12879 | continue; /* continue processing argv (bash compat) */ |
| 12891 | } | 12880 | } |
| 12881 | /* alias SOMETHING_WITHOUT_EQUAL_SIGN */ | ||
| 12892 | //bb_error_msg("%s:%d: -> find_alias_slot", __func__, __LINE__); | 12882 | //bb_error_msg("%s:%d: -> find_alias_slot", __func__, __LINE__); |
| 12893 | alias = *find_alias_slot(*argv, eq); | 12883 | alias = *find_alias_slot(*argv, eq); |
| 12894 | if (alias) { | 12884 | if (alias) { |
| 12895 | //todo: use NAME='VALUE' format, not NAME=VALUE | 12885 | //todo: use NAME='VALUE' format, not NAME=VALUE |
| 12896 | printf("alias %s\n", alias->str); | 12886 | print_pfx_escaped_nl("alias", alias->str); |
| 12897 | } else { | 12887 | } else { |
| 12898 | bb_error_msg("unalias: '%s': not found" + 2, *argv); | 12888 | bb_error_msg("unalias: '%s': not found" + 2, *argv); |
| 12899 | /* return 1; - no, continue processing argv (bash compat) */ | 12889 | /* return 1; - no, continue processing argv (bash compat) */ |
