aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2016-10-26 22:29:11 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2016-10-26 22:29:11 +0200
commit65a8b859a9a3f2bb4a62c15ca1f4d01288593734 (patch)
tree11965425b70a8cb6f40a7ad1d4d64e730be313bb /shell
parent0e081d01a8ae37df11af612eb65d858c1c0f28be (diff)
downloadbusybox-w32-65a8b859a9a3f2bb4a62c15ca1f4d01288593734.tar.gz
busybox-w32-65a8b859a9a3f2bb4a62c15ca1f4d01288593734.tar.bz2
busybox-w32-65a8b859a9a3f2bb4a62c15ca1f4d01288593734.zip
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>
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c31
1 files changed, 11 insertions, 20 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 8bf02e6a7..133b2d40e 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -7467,13 +7467,7 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) char *cmd, char **argv, char **
7467#else 7467#else
7468 execve(cmd, argv, envp); 7468 execve(cmd, argv, envp);
7469#endif 7469#endif
7470 if (cmd == (char*) bb_busybox_exec_path) { 7470 if (cmd != (char*) bb_busybox_exec_path && errno == ENOEXEC) {
7471 /* We already visited ENOEXEC branch below, don't do it again */
7472//TODO: try execve(initial_argv0_of_shell, argv, envp) before giving up?
7473 free(argv);
7474 return;
7475 }
7476 if (errno == ENOEXEC) {
7477 /* Run "cmd" as a shell script: 7471 /* Run "cmd" as a shell script:
7478 * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html 7472 * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
7479 * "If the execve() function fails with ENOEXEC, the shell 7473 * "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 **
7490 * message and exit code 126. For one, this prevents attempts 7484 * message and exit code 126. For one, this prevents attempts
7491 * to interpret foreign ELF binaries as shell scripts. 7485 * to interpret foreign ELF binaries as shell scripts.
7492 */ 7486 */
7493 char **ap; 7487 argv[0] = cmd;
7494 char **new;
7495
7496 for (ap = argv; *ap; ap++)
7497 continue;
7498 new = ckmalloc((ap - argv + 2) * sizeof(new[0]));
7499 new[0] = (char*) "ash";
7500 new[1] = cmd;
7501 ap = new + 2;
7502 while ((*ap++ = *++argv) != NULL)
7503 continue;
7504 cmd = (char*) bb_busybox_exec_path; 7488 cmd = (char*) bb_busybox_exec_path;
7505 argv = new; 7489 /* NB: this is only possible because all callers of shellexec()
7490 * ensure that the argv[-1] slot exists!
7491 */
7492 argv--;
7493 argv[0] = (char*) "ash";
7506 goto repeat; 7494 goto repeat;
7507 } 7495 }
7508} 7496}
@@ -7510,6 +7498,7 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) char *cmd, char **argv, char **
7510/* 7498/*
7511 * Exec a program. Never returns. If you change this routine, you may 7499 * Exec a program. Never returns. If you change this routine, you may
7512 * have to change the find_command routine as well. 7500 * have to change the find_command routine as well.
7501 * argv[-1] must exist and be writable! See tryexec() for why.
7513 */ 7502 */
7514static void shellexec(char **, const char *, int) NORETURN; 7503static void shellexec(char **, const char *, int) NORETURN;
7515static void 7504static void
@@ -9415,7 +9404,9 @@ evalcommand(union node *cmd, int flags)
9415 argc++; 9404 argc++;
9416 } 9405 }
9417 9406
9418 argv = nargv = stalloc(sizeof(char *) * (argc + 1)); 9407 /* Reserve one extra spot at the front for shellexec. */
9408 nargv = stalloc(sizeof(char *) * (argc + 2));
9409 argv = ++nargv;
9419 for (sp = arglist.list; sp; sp = sp->next) { 9410 for (sp = arglist.list; sp; sp = sp->next) {
9420 TRACE(("evalcommand arg: %s\n", sp->text)); 9411 TRACE(("evalcommand arg: %s\n", sp->text));
9421 *nargv++ = sp->text; 9412 *nargv++ = sp->text;