diff options
author | Ron Yorston <rmy@pobox.com> | 2022-03-24 11:43:37 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2022-03-24 12:26:01 +0000 |
commit | 3e385d22cc57aacddafe38a1b6bcd55aa71d3c80 (patch) | |
tree | 8c8ac54290ec6010d76206c5bd0e47f92bf2b13f | |
parent | af41de68901d48753eb73491d54931a99d1a13b5 (diff) | |
download | busybox-w32-tilde.tar.gz busybox-w32-tilde.tar.bz2 busybox-w32-tilde.zip |
ash,hush: use HOME for tab completion and promptstilde
ash and hush correctly use the value of HOME for tilde expansion.
However the line editing code in libbb obtains the user's home
directory by calling getpwuid(). Thus tildes in tab completion
and prompts may be interpreted differently than in tilde expansion.
When the line editing code is invoked from a shell make it use the
shell's interpretation of tilde. This is similar to how GNU readline
and bash collaborate.
function old new delta
get_homedir_or_NULL 29 72 +43
optschanged 119 126 +7
hush_main 1204 1211 +7
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/0 up/down: 57/0) Total: 57 bytes
v2: Always check for HOME before trying the password database: this
is what GNU readline does.
Signed-off-by: Ron Yorston <rmy@pobox.com>
-rw-r--r-- | include/libbb.h | 11 | ||||
-rw-r--r-- | libbb/lineedit.c | 12 | ||||
-rw-r--r-- | shell/ash.c | 7 | ||||
-rw-r--r-- | shell/hush.c | 5 |
4 files changed, 19 insertions, 16 deletions
diff --git a/include/libbb.h b/include/libbb.h index 740c25528..1c9198945 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -1984,6 +1984,7 @@ unsigned size_from_HISTFILESIZE(const char *hp) FAST_FUNC; | |||
1984 | # define MAX_HISTORY 0 | 1984 | # define MAX_HISTORY 0 |
1985 | # endif | 1985 | # endif |
1986 | typedef const char *get_exe_name_t(int i) FAST_FUNC; | 1986 | typedef const char *get_exe_name_t(int i) FAST_FUNC; |
1987 | typedef const char *sh_get_var_t(const char *name) FAST_FUNC; | ||
1987 | typedef struct line_input_t { | 1988 | typedef struct line_input_t { |
1988 | int flags; | 1989 | int flags; |
1989 | int timeout; | 1990 | int timeout; |
@@ -1997,9 +1998,8 @@ typedef struct line_input_t { | |||
1997 | # if ENABLE_SHELL_ASH || ENABLE_SHELL_HUSH | 1998 | # if ENABLE_SHELL_ASH || ENABLE_SHELL_HUSH |
1998 | /* function to fetch additional application-specific names to match */ | 1999 | /* function to fetch additional application-specific names to match */ |
1999 | get_exe_name_t *get_exe_name; | 2000 | get_exe_name_t *get_exe_name; |
2000 | # define EDITING_HAS_get_exe_name 1 | 2001 | /* function to fetch value of shell variable */ |
2001 | # else | 2002 | sh_get_var_t *sh_get_var; |
2002 | # define EDITING_HAS_get_exe_name 0 | ||
2003 | # endif | 2003 | # endif |
2004 | # endif | 2004 | # endif |
2005 | # if MAX_HISTORY | 2005 | # if MAX_HISTORY |
@@ -2053,11 +2053,6 @@ int read_line_input(const char* prompt, char* command, int maxsize) FAST_FUNC; | |||
2053 | read_line_input(prompt, command, maxsize) | 2053 | read_line_input(prompt, command, maxsize) |
2054 | #endif | 2054 | #endif |
2055 | 2055 | ||
2056 | #ifndef EDITING_HAS_get_exe_name | ||
2057 | # define EDITING_HAS_get_exe_name 0 | ||
2058 | #endif | ||
2059 | |||
2060 | |||
2061 | #ifndef COMM_LEN | 2056 | #ifndef COMM_LEN |
2062 | # ifdef TASK_COMM_LEN | 2057 | # ifdef TASK_COMM_LEN |
2063 | enum { COMM_LEN = TASK_COMM_LEN }; | 2058 | enum { COMM_LEN = TASK_COMM_LEN }; |
diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 778511d16..06321825c 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c | |||
@@ -259,6 +259,16 @@ static const char *get_username_str(void) | |||
259 | 259 | ||
260 | static NOINLINE const char *get_homedir_or_NULL(void) | 260 | static NOINLINE const char *get_homedir_or_NULL(void) |
261 | { | 261 | { |
262 | const char *home; | ||
263 | |||
264 | #if ENABLE_SHELL_ASH || ENABLE_SHELL_HUSH | ||
265 | home = state->sh_get_var ? state->sh_get_var("HOME") : getenv("HOME"); | ||
266 | #else | ||
267 | home = getenv("HOME"); | ||
268 | #endif | ||
269 | if (home != NULL && home[0] != '\0') | ||
270 | return home; | ||
271 | |||
262 | if (!got_user_strings) | 272 | if (!got_user_strings) |
263 | get_user_strings(); | 273 | get_user_strings(); |
264 | return home_pwd_buf; | 274 | return home_pwd_buf; |
@@ -932,7 +942,7 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type) | |||
932 | continue; | 942 | continue; |
933 | } | 943 | } |
934 | # endif | 944 | # endif |
935 | # if EDITING_HAS_get_exe_name | 945 | # if ENABLE_SHELL_ASH || ENABLE_SHELL_HUSH |
936 | if (state->get_exe_name) { | 946 | if (state->get_exe_name) { |
937 | i = 0; | 947 | i = 0; |
938 | for (;;) { | 948 | for (;;) { |
diff --git a/shell/ash.c b/shell/ash.c index e8a1e853c..dd806b629 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -10554,7 +10554,7 @@ evalpipe(union node *n, int flags) | |||
10554 | } | 10554 | } |
10555 | 10555 | ||
10556 | /* setinteractive needs this forward reference */ | 10556 | /* setinteractive needs this forward reference */ |
10557 | #if EDITING_HAS_get_exe_name | 10557 | #if ENABLE_FEATURE_EDITING |
10558 | static const char *get_builtin_name(int i) FAST_FUNC; | 10558 | static const char *get_builtin_name(int i) FAST_FUNC; |
10559 | #endif | 10559 | #endif |
10560 | 10560 | ||
@@ -10591,9 +10591,8 @@ setinteractive(int on) | |||
10591 | #if ENABLE_FEATURE_EDITING | 10591 | #if ENABLE_FEATURE_EDITING |
10592 | if (!line_input_state) { | 10592 | if (!line_input_state) { |
10593 | line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP); | 10593 | line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP); |
10594 | # if EDITING_HAS_get_exe_name | ||
10595 | line_input_state->get_exe_name = get_builtin_name; | 10594 | line_input_state->get_exe_name = get_builtin_name; |
10596 | # endif | 10595 | line_input_state->sh_get_var = lookupvar; |
10597 | } | 10596 | } |
10598 | #endif | 10597 | #endif |
10599 | } | 10598 | } |
@@ -11096,7 +11095,7 @@ find_builtin(const char *name) | |||
11096 | return bp; | 11095 | return bp; |
11097 | } | 11096 | } |
11098 | 11097 | ||
11099 | #if EDITING_HAS_get_exe_name | 11098 | #if ENABLE_FEATURE_EDITING |
11100 | static const char * FAST_FUNC | 11099 | static const char * FAST_FUNC |
11101 | get_builtin_name(int i) | 11100 | get_builtin_name(int i) |
11102 | { | 11101 | { |
diff --git a/shell/hush.c b/shell/hush.c index ae81f0da5..051b123e7 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -8188,7 +8188,7 @@ static const struct built_in_command *find_builtin(const char *name) | |||
8188 | return find_builtin_helper(name, bltins2, &bltins2[ARRAY_SIZE(bltins2)]); | 8188 | return find_builtin_helper(name, bltins2, &bltins2[ARRAY_SIZE(bltins2)]); |
8189 | } | 8189 | } |
8190 | 8190 | ||
8191 | #if ENABLE_HUSH_JOB && EDITING_HAS_get_exe_name | 8191 | #if ENABLE_HUSH_JOB && ENABLE_FEATURE_EDITING |
8192 | static const char * FAST_FUNC get_builtin_name(int i) | 8192 | static const char * FAST_FUNC get_builtin_name(int i) |
8193 | { | 8193 | { |
8194 | if (/*i >= 0 && */ i < ARRAY_SIZE(bltins1)) { | 8194 | if (/*i >= 0 && */ i < ARRAY_SIZE(bltins1)) { |
@@ -10668,9 +10668,8 @@ int hush_main(int argc, char **argv) | |||
10668 | 10668 | ||
10669 | # if ENABLE_FEATURE_EDITING | 10669 | # if ENABLE_FEATURE_EDITING |
10670 | G.line_input_state = new_line_input_t(FOR_SHELL); | 10670 | G.line_input_state = new_line_input_t(FOR_SHELL); |
10671 | # if EDITING_HAS_get_exe_name | ||
10672 | G.line_input_state->get_exe_name = get_builtin_name; | 10671 | G.line_input_state->get_exe_name = get_builtin_name; |
10673 | # endif | 10672 | G.line_input_state->sh_get_var = get_local_var_value; |
10674 | # endif | 10673 | # endif |
10675 | # if ENABLE_HUSH_SAVEHISTORY && MAX_HISTORY > 0 | 10674 | # if ENABLE_HUSH_SAVEHISTORY && MAX_HISTORY > 0 |
10676 | { | 10675 | { |