From eea6647c658b56cd9fb99544e4c96b3628d0cd79 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Fri, 13 Jul 2007 10:09:06 +0000 Subject: 23671: command not found handler --- ChangeLog | 6 ++++++ Doc/Zsh/exec.yo | 12 ++++++++++++ Src/exec.c | 23 +++++++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/ChangeLog b/ChangeLog index 889468f9a..01b9dd7e6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2007-07-13 Peter Stephenson + + * 23671: Doc/Zsh/exec.yo, Src/exec.c: Function + command_not_found_handler can be defined to handle command + not found. + 2007-07-12 Clint Adams * 23674: Completion/Unix/Command/_git: merge in git clone diff --git a/Doc/Zsh/exec.yo b/Doc/Zsh/exec.yo index 0d53b14b8..30e4a61a2 100644 --- a/Doc/Zsh/exec.yo +++ b/Doc/Zsh/exec.yo @@ -5,6 +5,8 @@ sect(Command Execution) )\ cindex(command execution) cindex(execution, of commands) +cindex(command not found, handling of) +findex(command_not_found_handler) If a command name contains no slashes, the shell attempts to locate it. If there exists a shell function by that name, the function is invoked as described in noderef(Functions). If there exists @@ -23,3 +25,13 @@ is a file beginning with `tt(#!)', the remainder of the first line specifies an interpreter for the program. The shell will execute the specified interpreter on operating systems that do not handle this executable format in the kernel. + +If no external command is found but a function tt(command_not_found_handler) +exists the shell executes this function with all +command line arguments. The function should return status zero if it +successfully handled the command, or non-zero status if it failed. +In the latter case the standard handling is applied: `command not +found' is printed to standard error and the shell exits with status 127. +Note that the handler is executed in a subshell forked to execute +an external command, hence changes to directories, shell parameters, +etc. have no effect on the main shell. diff --git a/Src/exec.c b/Src/exec.c index 015753a83..ad088001e 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -468,6 +468,25 @@ isgooderr(int e, char *dir) e != ENOENT && e != ENOTDIR); } +/* + * Attempt to handle command not found. + * Return 0 if the condition was handled, non-zero otherwise. + */ + +/**/ +static int +commandnotfound(char *arg0, LinkList args) +{ + Shfunc shf = (Shfunc) + shfunctab->getnode(shfunctab, "command_not_found_handler"); + + if (!shf) + return 127; + + pushnode(args, arg0); + return doshfunc(shf->node.nam, shf->funcdef, args, shf->node.flags, 1); +} + /* execute an external command */ /**/ @@ -562,6 +581,8 @@ execute(LinkList args, int flags, int defpath) } if (!ps) { + if (commandnotfound(arg0, args) == 0) + _exit(0); zerr("command not found: %s", arg0); _exit(127); } @@ -624,6 +645,8 @@ execute(LinkList args, int flags, int defpath) if (eno) zerr("%e: %s", eno, arg0); + else if (commandnotfound(arg0, args) == 0) + _exit(0); else zerr("command not found: %s", arg0); _exit((eno == EACCES || eno == ENOEXEC) ? 126 : 127); -- cgit 1.4.1