[prev in list] [next in list] [prev in thread] [next in thread] 

List:       busybox
Subject:    [PATCH] ash: add support for command_not_found_handle hook function, like bash
From:       William Pitcock <nenolod () dereferenced ! org>
Date:       2017-10-19 17:33:04
Message-ID: 20171019173304.28564-1-nenolod () dereferenced ! org
[Download RAW message or body]

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@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;
 
-- 
2.14.2

_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic