ash: optimize tryexec(): avoid one allocation
There was a bug in tryexec which bbox had fixed in 2003. dash had a smaller fix in 2007. Copy it. It is smaller, although it is also more quirky (requires argv[-1] to exist). Upstream commit 1: Date: Mon, 15 Oct 2007 20:24:28 +0800 [EXEC] Fixed execing of scripts with no hash-bang The function tryexec used the original name instead of the path found through PATH search. This patch fixes that. Test case: trap 'rm -f $TMP' EXIT TMP=$(tempfile -s nosuchthing) cat <<- EOF > $TMP echo OK EOF chmod u+x $TMP cd / PATH=${TMP%/*} ${TMP##*/} Old result: /bin/sh: Can't open filelgY4Fanosuchthing New result: OK Upstream commit 2: Date: Sun, 23 Dec 2007 11:02:26 +0800 [EVAL] Fix bad pointer arithmetic in evalcommand dash dies on sparc with a SIGBUS due to an arithmetic error introduced with commit 03b4958, this patch fixes it. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> function old new delta evalcommand 1261 1264 +3 dotcmd 321 319 -2 tryexec 115 64 -51 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/2 up/down: 3/-53) Total: -50 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
0e081d01a8
commit
65a8b859a9
31
shell/ash.c
31
shell/ash.c
@ -7467,13 +7467,7 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) char *cmd, char **argv, char **
|
|||||||
#else
|
#else
|
||||||
execve(cmd, argv, envp);
|
execve(cmd, argv, envp);
|
||||||
#endif
|
#endif
|
||||||
if (cmd == (char*) bb_busybox_exec_path) {
|
if (cmd != (char*) bb_busybox_exec_path && errno == ENOEXEC) {
|
||||||
/* We already visited ENOEXEC branch below, don't do it again */
|
|
||||||
//TODO: try execve(initial_argv0_of_shell, argv, envp) before giving up?
|
|
||||||
free(argv);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (errno == ENOEXEC) {
|
|
||||||
/* Run "cmd" as a shell script:
|
/* Run "cmd" as a shell script:
|
||||||
* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
|
* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
|
||||||
* "If the execve() function fails with ENOEXEC, the shell
|
* "If the execve() function fails with ENOEXEC, the shell
|
||||||
@ -7490,19 +7484,13 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) char *cmd, char **argv, char **
|
|||||||
* message and exit code 126. For one, this prevents attempts
|
* message and exit code 126. For one, this prevents attempts
|
||||||
* to interpret foreign ELF binaries as shell scripts.
|
* to interpret foreign ELF binaries as shell scripts.
|
||||||
*/
|
*/
|
||||||
char **ap;
|
argv[0] = cmd;
|
||||||
char **new;
|
|
||||||
|
|
||||||
for (ap = argv; *ap; ap++)
|
|
||||||
continue;
|
|
||||||
new = ckmalloc((ap - argv + 2) * sizeof(new[0]));
|
|
||||||
new[0] = (char*) "ash";
|
|
||||||
new[1] = cmd;
|
|
||||||
ap = new + 2;
|
|
||||||
while ((*ap++ = *++argv) != NULL)
|
|
||||||
continue;
|
|
||||||
cmd = (char*) bb_busybox_exec_path;
|
cmd = (char*) bb_busybox_exec_path;
|
||||||
argv = new;
|
/* NB: this is only possible because all callers of shellexec()
|
||||||
|
* ensure that the argv[-1] slot exists!
|
||||||
|
*/
|
||||||
|
argv--;
|
||||||
|
argv[0] = (char*) "ash";
|
||||||
goto repeat;
|
goto repeat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -7510,6 +7498,7 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) char *cmd, char **argv, char **
|
|||||||
/*
|
/*
|
||||||
* Exec a program. Never returns. If you change this routine, you may
|
* Exec a program. Never returns. If you change this routine, you may
|
||||||
* have to change the find_command routine as well.
|
* have to change the find_command routine as well.
|
||||||
|
* argv[-1] must exist and be writable! See tryexec() for why.
|
||||||
*/
|
*/
|
||||||
static void shellexec(char **, const char *, int) NORETURN;
|
static void shellexec(char **, const char *, int) NORETURN;
|
||||||
static void
|
static void
|
||||||
@ -9415,7 +9404,9 @@ evalcommand(union node *cmd, int flags)
|
|||||||
argc++;
|
argc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
argv = nargv = stalloc(sizeof(char *) * (argc + 1));
|
/* Reserve one extra spot at the front for shellexec. */
|
||||||
|
nargv = stalloc(sizeof(char *) * (argc + 2));
|
||||||
|
argv = ++nargv;
|
||||||
for (sp = arglist.list; sp; sp = sp->next) {
|
for (sp = arglist.list; sp; sp = sp->next) {
|
||||||
TRACE(("evalcommand arg: %s\n", sp->text));
|
TRACE(("evalcommand arg: %s\n", sp->text));
|
||||||
*nargv++ = sp->text;
|
*nargv++ = sp->text;
|
||||||
|
Loading…
Reference in New Issue
Block a user