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)
This commit is contained in:
Denis Vlasenko 2008-05-30 22:28:32 +00:00
parent f9a0784144
commit 447bd66837
5 changed files with 21 additions and 6 deletions

View File

@ -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";
}
/*

View File

@ -0,0 +1,2 @@
./: cannot execute
126

View File

@ -0,0 +1,2 @@
./
echo $?

View File

@ -0,0 +1,2 @@
./does_exist_for_sure: not found
127

View File

@ -0,0 +1,2 @@
./does_exist_for_sure
echo $?