If running the external command fails in "argv mode" (ie. when
not using the shell), then exit with either 126 or 127 as defined
by POSIX.
This is mostly the same as what bash does, see
execute_cmd.c:shell_execve in the bash sources.
Note: saving errno around perror(3) if necessary, otherwise you will
see different behaviour between verbose and non-verbose mode. In
non-verbose mode, perror(3) tried to print to a closed file
descriptor, failing and overwriting errno. That took some time to
debug.
---
lib/command.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/lib/command.c b/lib/command.c
index 3d8bc7dbf..36f953dcf 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -539,7 +539,7 @@ static void
run_child (struct command *cmd)
{
struct sigaction sa;
- int i, fd, max_fd, r;
+ int i, err, fd, max_fd, r;
char status_string[80];
#ifdef HAVE_SETRLIMIT
struct child_rlimits *child_rlimit;
@@ -614,8 +614,12 @@ run_child (struct command *cmd)
switch (cmd->style) {
case COMMAND_STYLE_EXECV:
execvp (cmd->argv.argv[0], cmd->argv.argv);
+ err = errno;
perror (cmd->argv.argv[0]);
- _exit (EXIT_FAILURE);
+ /* These error codes are defined in POSIX and meant to be the
+ * same as the shell.
+ */
+ _exit (err == ENOENT ? 127 : 126);
case COMMAND_STYLE_SYSTEM:
r = system (cmd->string.str);
--
2.13.2