diff options
author | Ron Yorston <rmy@pobox.com> | 2022-05-06 08:26:55 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2022-05-06 09:30:43 +0100 |
commit | 26ba73098e714459e3294679228a1d54eed14799 (patch) | |
tree | 5e5dda2adbf6577276baf372626465213fd2f1b9 /shell | |
parent | 3b5042430fc4b82d44e0430f9ecc21a9228d1651 (diff) | |
download | busybox-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.c | 46 |
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 | */ |
8986 | static struct builtincmd *find_builtin(const char *name); | ||
8986 | static void shellexec(char *prog, char **argv, const char *path, int idx) NORETURN; | 8987 | static void shellexec(char *prog, char **argv, const char *path, int idx) NORETURN; |
8987 | static void shellexec(char *prog, char **argv, const char *path, int idx) | 8988 | static 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 | ||