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:
parent
f9a0784144
commit
447bd66837
19
shell/msh.c
19
shell/msh.c
@ -594,7 +594,7 @@ static struct op *dowholefile(int /*, int*/);
|
|||||||
/* Globals */
|
/* Globals */
|
||||||
static char **dolv;
|
static char **dolv;
|
||||||
static int dolc;
|
static int dolc;
|
||||||
static int exstat;
|
static uint8_t exstat;
|
||||||
static smallint gflg; /* (seems to be a parse error indicator) */
|
static smallint gflg; /* (seems to be a parse error indicator) */
|
||||||
static smallint interactive; /* Is this an interactive shell */
|
static smallint interactive; /* Is this an interactive shell */
|
||||||
static smallint execflg;
|
static smallint execflg;
|
||||||
@ -806,7 +806,8 @@ static void warn(const char *s)
|
|||||||
{
|
{
|
||||||
if (*s) {
|
if (*s) {
|
||||||
prs(s);
|
prs(s);
|
||||||
exstat = -1;
|
if (!exstat)
|
||||||
|
exstat = 255;
|
||||||
}
|
}
|
||||||
prs("\n");
|
prs("\n");
|
||||||
if (FLAG['e'])
|
if (FLAG['e'])
|
||||||
@ -3071,8 +3072,6 @@ static const char *rexecve(char *c, char **v, char **envp)
|
|||||||
if (tp != global_env.linep)
|
if (tp != global_env.linep)
|
||||||
*tp++ = '/';
|
*tp++ = '/';
|
||||||
strcpy(tp, c);
|
strcpy(tp, c);
|
||||||
//for (i = 0; (*tp++ = c[i++]) != '\0';)
|
|
||||||
// continue;
|
|
||||||
|
|
||||||
DBGPRINTF3(("REXECVE: global_env.linep is %s\n", global_env.linep));
|
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) {
|
switch (errno) {
|
||||||
case ENOEXEC:
|
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 = global_env.linep;
|
||||||
v--;
|
v--;
|
||||||
tp = *v;
|
tp = *v;
|
||||||
*v = global_env.linep;
|
*v = (char*)DEFAULT_SHELL;
|
||||||
execve(DEFAULT_SHELL, v, envp);
|
execve(DEFAULT_SHELL, v, envp);
|
||||||
*v = tp;
|
*v = tp;
|
||||||
return "no shell";
|
return "no shell";
|
||||||
@ -3095,7 +3097,12 @@ static const char *rexecve(char *c, char **v, char **envp)
|
|||||||
return "argument list too long";
|
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";
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
2
shell/msh_test/msh-execution/exitcode_EACCES.right
Normal file
2
shell/msh_test/msh-execution/exitcode_EACCES.right
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
./: cannot execute
|
||||||
|
126
|
2
shell/msh_test/msh-execution/exitcode_EACCES.tests
Executable file
2
shell/msh_test/msh-execution/exitcode_EACCES.tests
Executable file
@ -0,0 +1,2 @@
|
|||||||
|
./
|
||||||
|
echo $?
|
2
shell/msh_test/msh-execution/exitcode_ENOENT.right
Normal file
2
shell/msh_test/msh-execution/exitcode_ENOENT.right
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
./does_exist_for_sure: not found
|
||||||
|
127
|
2
shell/msh_test/msh-execution/exitcode_ENOENT.tests
Executable file
2
shell/msh_test/msh-execution/exitcode_ENOENT.tests
Executable file
@ -0,0 +1,2 @@
|
|||||||
|
./does_exist_for_sure
|
||||||
|
echo $?
|
Loading…
Reference in New Issue
Block a user