msh: fix the case where the file has exec bit but can't be run directly
(run "$SHELL $file" instead)
msh: fix exit codes when command is not found or can't be execed
(with testcases)
diff --git a/shell/msh.c b/shell/msh.c
index 9e06a3b..840c8bb 100644
--- a/shell/msh.c
+++ b/shell/msh.c
@@ -594,7 +594,7 @@
/* Globals */
static char **dolv;
static int dolc;
-static int exstat;
+static uint8_t exstat;
static smallint gflg; /* (seems to be a parse error indicator) */
static smallint interactive; /* Is this an interactive shell */
static smallint execflg;
@@ -806,7 +806,8 @@
{
if (*s) {
prs(s);
- exstat = -1;
+ if (!exstat)
+ exstat = 255;
}
prs("\n");
if (FLAG['e'])
@@ -3071,8 +3072,6 @@
if (tp != global_env.linep)
*tp++ = '/';
strcpy(tp, c);
- //for (i = 0; (*tp++ = c[i++]) != '\0';)
- // continue;
DBGPRINTF3(("REXECVE: global_env.linep is %s\n", global_env.linep));
@@ -3080,10 +3079,13 @@
switch (errno) {
case ENOEXEC:
+ /* File is executable but file format isnt recognized */
+ /* Run it as a shell script */
+ /* (execve above didnt do it itself, unlike execvp) */
*v = global_env.linep;
v--;
tp = *v;
- *v = global_env.linep;
+ *v = (char*)DEFAULT_SHELL;
execve(DEFAULT_SHELL, v, envp);
*v = tp;
return "no shell";
@@ -3095,7 +3097,12 @@
return "argument list too long";
}
}
- return errno == ENOENT ? "not found" : "cannot execute";
+ if (errno == ENOENT) {
+ exstat = 127; /* standards require this */
+ return "not found";
+ }
+ exstat = 126; /* mimic bash */
+ return "cannot execute";
}
/*
diff --git a/shell/msh_test/msh-execution/exitcode_EACCES.right b/shell/msh_test/msh-execution/exitcode_EACCES.right
new file mode 100644
index 0000000..b13682c
--- /dev/null
+++ b/shell/msh_test/msh-execution/exitcode_EACCES.right
@@ -0,0 +1,2 @@
+./: cannot execute
+126
diff --git a/shell/msh_test/msh-execution/exitcode_EACCES.tests b/shell/msh_test/msh-execution/exitcode_EACCES.tests
new file mode 100755
index 0000000..26b5c61
--- /dev/null
+++ b/shell/msh_test/msh-execution/exitcode_EACCES.tests
@@ -0,0 +1,2 @@
+./
+echo $?
diff --git a/shell/msh_test/msh-execution/exitcode_ENOENT.right b/shell/msh_test/msh-execution/exitcode_ENOENT.right
new file mode 100644
index 0000000..e2bad05
--- /dev/null
+++ b/shell/msh_test/msh-execution/exitcode_ENOENT.right
@@ -0,0 +1,2 @@
+./does_exist_for_sure: not found
+127
diff --git a/shell/msh_test/msh-execution/exitcode_ENOENT.tests b/shell/msh_test/msh-execution/exitcode_ENOENT.tests
new file mode 100755
index 0000000..c886653
--- /dev/null
+++ b/shell/msh_test/msh-execution/exitcode_ENOENT.tests
@@ -0,0 +1,2 @@
+./does_exist_for_sure
+echo $?