[PATCH] ash: add support for command_not_found_handle hook function, like bash

Denys Vlasenko vda.linux at googlemail.com
Wed Jan 24 17:35:42 UTC 2018


On Thu, Oct 19, 2017 at 7:33 PM, William Pitcock
<nenolod at dereferenced.org> wrote:
> This implements support for the command_not_found_handle hook function, which is
> useful for allowing package managers to suggest packages which could provide the
> command.
>
> Unlike bash, however, we ignore exit codes from the hook function and always return
> the correct POSIX error code (EX_NOTFOUND).
>
> Signed-off-by: William Pitcock <nenolod at dereferenced.org>
> ---
>  shell/ash.c | 24 ++++++++++++++++++++++--
>  1 file changed, 22 insertions(+), 2 deletions(-)
>
> diff --git a/shell/ash.c b/shell/ash.c
> index 88e607f08..c3c4f4e93 100644
> --- a/shell/ash.c
> +++ b/shell/ash.c
> @@ -132,6 +132,15 @@
>  //config:      you to run the specified command or builtin,
>  //config:      even when there is a function with the same name.
>  //config:
> +//config:config ASH_COMMAND_NOT_FOUND_HOOK
> +//config:      bool "command_not_found_handle hook support"
> +//config:      default y
> +//config:      depends on ASH || SH_IS_ASH || BASH_IS_ASH
> +//config:      help
> +//config:      Enable support for the 'command_not_found_handle' hook function,
> +//config:      from GNU bash, which allows for alternative command not found
> +//config:      handling.
> +//config:
>  //config:endif # ash options
>
>  //applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP))
> @@ -13123,8 +13132,19 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path)
>         /* We failed.  If there was an entry for this command, delete it */
>         if (cmdp && updatetbl)
>                 delete_cmd_entry();
> -       if (act & DO_ERR)
> -               ash_msg("%s: %s", name, errmsg(e, "not found"));
> +       if (act & DO_ERR) {
> +#ifdef CONFIG_ASH_COMMAND_NOT_FOUND_HOOK
> +#define HOOKFN_NAME "command_not_found_handle"
> +               char hookfn_name[] = HOOKFN_NAME;
> +               struct tblentry *hookp = cmdlookup(hookfn_name, 0);
> +               if (hookp != NULL && hookp->cmdtype == CMDFUNCTION) {
> +                       evalfun(hookp->param.func, 2, (char *[]){ hookfn_name, name }, 0);
> +                       entry->cmdtype = CMDUNKNOWN;
> +                       return;
> +               } else
> +#endif
> +                       ash_msg("%s: %s", name, errmsg(e, "not found"));
> +       }
>         entry->cmdtype = CMDUNKNOWN;
>         return;
>

Applied with some edits. Thanks.


More information about the busybox mailing list