[PATCH v2] ash,hush: use HOME for tab completion and prompts

Denys Vlasenko vda.linux at googlemail.com
Sun Jun 26 16:10:59 UTC 2022


Applied, thank you.

On Thu, Mar 24, 2022 at 1:17 PM Ron Yorston <rmy at pobox.com> wrote:
>
> 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 at pobox.com>
> ---
>  include/libbb.h  | 11 +++--------
>  libbb/lineedit.c | 12 +++++++++++-
>  shell/ash.c      |  7 +++----
>  shell/hush.c     |  5 ++---
>  4 files changed, 19 insertions(+), 16 deletions(-)
>
> diff --git a/include/libbb.h b/include/libbb.h
> index 6aeec249d..abbc9ac59 100644
> --- a/include/libbb.h
> +++ b/include/libbb.h
> @@ -1924,6 +1924,7 @@ unsigned size_from_HISTFILESIZE(const char *hp) FAST_FUNC;
>  #  define MAX_HISTORY 0
>  # endif
>  typedef const char *get_exe_name_t(int i) FAST_FUNC;
> +typedef const char *sh_get_var_t(const char *name) FAST_FUNC;
>  typedef struct line_input_t {
>         int flags;
>         int timeout;
> @@ -1937,9 +1938,8 @@ typedef struct line_input_t {
>  #  if ENABLE_SHELL_ASH || ENABLE_SHELL_HUSH
>         /* function to fetch additional application-specific names to match */
>         get_exe_name_t *get_exe_name;
> -#   define EDITING_HAS_get_exe_name 1
> -#  else
> -#   define EDITING_HAS_get_exe_name 0
> +       /* function to fetch value of shell variable */
> +       sh_get_var_t *sh_get_var;
>  #  endif
>  # endif
>  # if MAX_HISTORY
> @@ -1993,11 +1993,6 @@ int read_line_input(const char* prompt, char* command, int maxsize) FAST_FUNC;
>         read_line_input(prompt, command, maxsize)
>  #endif
>
> -#ifndef EDITING_HAS_get_exe_name
> -# define EDITING_HAS_get_exe_name 0
> -#endif
> -
> -
>  #ifndef COMM_LEN
>  # ifdef TASK_COMM_LEN
>  enum { COMM_LEN = TASK_COMM_LEN };
> diff --git a/libbb/lineedit.c b/libbb/lineedit.c
> index 82624757e..fd9377327 100644
> --- a/libbb/lineedit.c
> +++ b/libbb/lineedit.c
> @@ -259,6 +259,16 @@ static const char *get_username_str(void)
>
>  static NOINLINE const char *get_homedir_or_NULL(void)
>  {
> +       const char *home;
> +
> +#if ENABLE_SHELL_ASH || ENABLE_SHELL_HUSH
> +       home = state->sh_get_var ? state->sh_get_var("HOME") : getenv("HOME");
> +#else
> +       home = getenv("HOME");
> +#endif
> +       if (home != NULL && home[0] != '\0')
> +               return home;
> +
>         if (!got_user_strings)
>                 get_user_strings();
>         return home_pwd_buf;
> @@ -861,7 +871,7 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type)
>                                 continue;
>                 }
>  # endif
> -# if EDITING_HAS_get_exe_name
> +# if ENABLE_SHELL_ASH || ENABLE_SHELL_HUSH
>                 if (state->get_exe_name) {
>                         i = 0;
>                         for (;;) {
> diff --git a/shell/ash.c b/shell/ash.c
> index ef4a47afe..d29de37b7 100644
> --- a/shell/ash.c
> +++ b/shell/ash.c
> @@ -9720,7 +9720,7 @@ evalpipe(union node *n, int flags)
>  }
>
>  /* setinteractive needs this forward reference */
> -#if EDITING_HAS_get_exe_name
> +#if ENABLE_FEATURE_EDITING
>  static const char *get_builtin_name(int i) FAST_FUNC;
>  #endif
>
> @@ -9757,9 +9757,8 @@ setinteractive(int on)
>  #if ENABLE_FEATURE_EDITING
>                 if (!line_input_state) {
>                         line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP);
> -# if EDITING_HAS_get_exe_name
>                         line_input_state->get_exe_name = get_builtin_name;
> -# endif
> +                       line_input_state->sh_get_var = lookupvar;
>                 }
>  #endif
>         }
> @@ -10262,7 +10261,7 @@ find_builtin(const char *name)
>         return bp;
>  }
>
> -#if EDITING_HAS_get_exe_name
> +#if ENABLE_FEATURE_EDITING
>  static const char * FAST_FUNC
>  get_builtin_name(int i)
>  {
> 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)
>         return find_builtin_helper(name, bltins2, &bltins2[ARRAY_SIZE(bltins2)]);
>  }
>
> -#if ENABLE_HUSH_JOB && EDITING_HAS_get_exe_name
> +#if ENABLE_HUSH_JOB && ENABLE_FEATURE_EDITING
>  static const char * FAST_FUNC get_builtin_name(int i)
>  {
>         if (/*i >= 0 && */ i < ARRAY_SIZE(bltins1)) {
> @@ -10668,9 +10668,8 @@ int hush_main(int argc, char **argv)
>
>  # if ENABLE_FEATURE_EDITING
>                 G.line_input_state = new_line_input_t(FOR_SHELL);
> -#  if EDITING_HAS_get_exe_name
>                 G.line_input_state->get_exe_name = get_builtin_name;
> -#  endif
> +               G.line_input_state->sh_get_var = get_local_var_value;
>  # endif
>  # if ENABLE_HUSH_SAVEHISTORY && MAX_HISTORY > 0
>                 {
> --
> 2.35.1
>
> _______________________________________________
> busybox mailing list
> busybox at busybox.net
> http://lists.busybox.net/mailman/listinfo/busybox


More information about the busybox mailing list