summaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorDenis Vlasenko2008-05-30 22:28:32 +0000
committerDenis Vlasenko2008-05-30 22:28:32 +0000
commit447bd6683729eb6d0f09e30eb68add6297881d01 (patch)
tree778c20dc4b7f7f176ea43934d8fca9ac3056f5cc /shell
parentf9a07841441e63a96d1a416f68ee2eeb78bface0 (diff)
downloadbusybox-447bd6683729eb6d0f09e30eb68add6297881d01.zip
busybox-447bd6683729eb6d0f09e30eb68add6297881d01.tar.gz
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)
Diffstat (limited to 'shell')
-rw-r--r--shell/msh.c19
-rw-r--r--shell/msh_test/msh-execution/exitcode_EACCES.right2
-rwxr-xr-xshell/msh_test/msh-execution/exitcode_EACCES.tests2
-rw-r--r--shell/msh_test/msh-execution/exitcode_ENOENT.right2
-rwxr-xr-xshell/msh_test/msh-execution/exitcode_ENOENT.tests2
5 files changed, 21 insertions, 6 deletions
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 @@ static struct op *dowholefile(int /*, int*/);
/* 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 @@ static void warn(const char *s)
{
if (*s) {
prs(s);
- exstat = -1;
+ if (!exstat)
+ exstat = 255;
}
prs("\n");
if (FLAG['e'])
@@ -3071,8 +3072,6 @@ static const char *rexecve(char *c, char **v, char **envp)
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 @@ static const char *rexecve(char *c, char **v, char **envp)
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 @@ static const char *rexecve(char *c, char **v, char **envp)
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 $?