aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2022-05-06 08:26:55 +0100
committerRon Yorston <rmy@pobox.com>2022-05-06 09:30:43 +0100
commit26ba73098e714459e3294679228a1d54eed14799 (patch)
tree5e5dda2adbf6577276baf372626465213fd2f1b9 /shell
parent3b5042430fc4b82d44e0430f9ecc21a9228d1651 (diff)
downloadbusybox-w32-26ba73098e714459e3294679228a1d54eed14799.tar.gz
busybox-w32-26ba73098e714459e3294679228a1d54eed14799.tar.bz2
busybox-w32-26ba73098e714459e3294679228a1d54eed14799.zip
win32: search PATH for missing Unix-style executables
Commit 41ef232fc5 (win32: use built-in applets for non-existent binaries with Unix-style paths) alters what happens when trying to find an executable. If all of the following apply: - the pathname starts with one of the standard directories for Unix executables (/bin, /usr/bin, /sbin, /usr/sbin); - the file isn't found relative to the system root; - the basename matches an applet then the applet is run. Further extend the procedure so that if the first two conditions are met and either: - the PREFER_APPLETS and SH_STANDALONE features are enabled and the basename *doesn't* match an applet or - the PREFER_APPLETS and SH_STANDALONE features are disabled then PATH is searched for the basename. This affects: - how interpreters and binaries are spawned by mingw_spawn_interpreter() and mingw_spawnvp(); - how 'which' and the shell search for binaries. Special steps need to be taken in the shell to avoid treating shell built-ins and functions as applets. As a consequence of this change: - An executable that isn't an applet, say curl.exe, can be run as /usr/bin/curl so long as it's in a directory in PATH. It doesn't have to be in C:/usr/bin. - If the PREFER_APPLETS and SH_STANDALONE features are disabled binaries can be run using paths referring to standard Unix directories even if they're installed elsewhere in PATH.
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c46
1 files changed, 23 insertions, 23 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 97075ed5f..6c1e58d6f 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -8983,6 +8983,7 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, c
8983 * have to change the find_command routine as well. 8983 * have to change the find_command routine as well.
8984 * argv[-1] must exist and be writable! See tryexec() for why. 8984 * argv[-1] must exist and be writable! See tryexec() for why.
8985 */ 8985 */
8986static struct builtincmd *find_builtin(const char *name);
8986static void shellexec(char *prog, char **argv, const char *path, int idx) NORETURN; 8987static void shellexec(char *prog, char **argv, const char *path, int idx) NORETURN;
8987static void shellexec(char *prog, char **argv, const char *path, int idx) 8988static void shellexec(char *prog, char **argv, const char *path, int idx)
8988{ 8989{
@@ -9011,9 +9012,7 @@ static void shellexec(char *prog, char **argv, const char *path, int idx)
9011#endif 9012#endif
9012 ) { 9013 ) {
9013#if ENABLE_PLATFORM_MINGW32 9014#if ENABLE_PLATFORM_MINGW32
9014# if ENABLE_FEATURE_SH_STANDALONE
9015 char *oldprog = prog; 9015 char *oldprog = prog;
9016# endif
9017 prog = stack_add_system_drive(prog); 9016 prog = stack_add_system_drive(prog);
9018#endif 9017#endif
9019 tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) prog, argv, envp); 9018 tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) prog, argv, envp);
@@ -9025,16 +9024,17 @@ static void shellexec(char *prog, char **argv, const char *path, int idx)
9025 goto try_PATH; 9024 goto try_PATH;
9026 } 9025 }
9027 e = errno; 9026 e = errno;
9028#if ENABLE_PLATFORM_MINGW32 && ENABLE_FEATURE_SH_STANDALONE 9027#if ENABLE_PLATFORM_MINGW32
9029 if (unix_path(oldprog)) { 9028 if (unix_path(oldprog) && !find_builtin(bb_basename(oldprog))) {
9029# if ENABLE_FEATURE_SH_STANDALONE
9030 const char *name = bb_basename(oldprog); 9030 const char *name = bb_basename(oldprog);
9031 if ((applet_no = find_applet_by_name(name)) >= 0) { 9031 if ((applet_no = find_applet_by_name(name)) >= 0) {
9032 tryexec(applet_no, name, argv, envp); 9032 tryexec(applet_no, name, argv, envp);
9033 e = errno; 9033 e = errno;
9034 } 9034 }
9035 else { 9035# endif
9036 e = ENOENT; 9036 argv[0] = (char *)bb_basename(oldprog);
9037 } 9037 goto try_PATH;
9038 } 9038 }
9039#endif 9039#endif
9040 } else { 9040 } else {
@@ -9481,6 +9481,10 @@ describe_command(char *command, const char *path, int describe_command_verbose)
9481 p = command; 9481 p = command;
9482#endif 9482#endif
9483 } else { 9483 } else {
9484#if ENABLE_PLATFORM_MINGW32
9485 if (unix_path(command))
9486 command = (char *)bb_basename(command);
9487#endif
9484 do { 9488 do {
9485 padvance(&path, command); 9489 padvance(&path, command);
9486 } while (--j >= 0); 9490 } while (--j >= 0);
@@ -14658,24 +14662,20 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path)
14658#else /* ENABLE_PLATFORM_MINGW32 */ 14662#else /* ENABLE_PLATFORM_MINGW32 */
14659 /* If name contains a slash or drive prefix, don't use PATH or hash table */ 14663 /* If name contains a slash or drive prefix, don't use PATH or hash table */
14660 if (has_path(name)) { 14664 if (has_path(name)) {
14661 fullname = stack_add_system_drive(name);
14662 entry->u.index = -1; 14665 entry->u.index = -1;
14663 if (act & DO_ABS) {
14664 if (!add_win32_extension(fullname) && stat(fullname, &statb) < 0) {
14665# if ENABLE_FEATURE_SH_STANDALONE
14666 if (unix_path(name) &&
14667 find_applet_by_name(bb_basename(name)) >= 0) {
14668 entry->cmdtype = CMDNORMAL;
14669 entry->u.index = INT_MIN;
14670 return;
14671 }
14672# endif
14673 entry->cmdtype = CMDUNKNOWN;
14674 return;
14675 }
14676 }
14677 entry->cmdtype = CMDNORMAL; 14666 entry->cmdtype = CMDNORMAL;
14678 return; 14667 fullname = stack_add_system_drive(name);
14668 if (add_win32_extension(fullname) || file_is_executable(fullname)) {
14669 return;
14670 } else if (unix_path(name) && !find_builtin(bb_basename(name))) {
14671 name = (char *)bb_basename(name);
14672 act |= DO_NOFUNC;
14673 } else if (act & DO_ABS) {
14674 entry->cmdtype = CMDUNKNOWN;
14675 return;
14676 } else {
14677 return;
14678 }
14679 } 14679 }
14680#endif /* ENABLE_PLATFORM_MINGW32 */ 14680#endif /* ENABLE_PLATFORM_MINGW32 */
14681 14681