diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-05-30 22:28:32 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-05-30 22:28:32 +0000 |
commit | 447bd6683729eb6d0f09e30eb68add6297881d01 (patch) | |
tree | 778c20dc4b7f7f176ea43934d8fca9ac3056f5cc | |
parent | f9a07841441e63a96d1a416f68ee2eeb78bface0 (diff) |
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)
-rw-r--r-- | shell/msh.c | 19 | ||||
-rw-r--r-- | shell/msh_test/msh-execution/exitcode_EACCES.right | 2 | ||||
-rwxr-xr-x | shell/msh_test/msh-execution/exitcode_EACCES.tests | 2 | ||||
-rw-r--r-- | shell/msh_test/msh-execution/exitcode_ENOENT.right | 2 | ||||
-rwxr-xr-x | shell/msh_test/msh-execution/exitcode_ENOENT.tests | 2 |
5 files changed, 21 insertions, 6 deletions
diff --git a/shell/msh.c b/shell/msh.c index 9e06a3bff..840c8bb93 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 000000000..b13682cde --- /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 000000000..26b5c6116 --- /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 000000000..e2bad05e2 --- /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 000000000..c8866532b --- /dev/null +++ b/shell/msh_test/msh-execution/exitcode_ENOENT.tests @@ -0,0 +1,2 @@ +./does_exist_for_sure +echo $? |