diff options
author | Ron Yorston <rmy@pobox.com> | 2020-08-13 14:27:56 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2020-08-13 14:58:01 +0100 |
commit | 41ef232fc522d91f29931ea4ee547432ca8899ee (patch) | |
tree | d2acfdc43839b68b569debb4494d5c7fbd8bc66b /win32 | |
parent | 16e5930a65f3c7c570b8a0dda8daa19ab4792fa2 (diff) | |
download | busybox-w32-41ef232fc522d91f29931ea4ee547432ca8899ee.tar.gz busybox-w32-41ef232fc522d91f29931ea4ee547432ca8899ee.tar.bz2 busybox-w32-41ef232fc522d91f29931ea4ee547432ca8899ee.zip |
win32: use built-in applets for non-existent binaries with Unix-style paths
Shell scripts moved from Unix may contain hard-coded paths to
binaries such as /bin/sh. A recent commit made it possible to
execute such binaries reliably, but that does require them to be
installed. As an alternative solution: if a binary with a
standard Unix path prefix can't be found but is available as a
built-in applet, run the applet.
Add the function unix_path() to detect paths starting with /bin,
/usr/bin, /sbin or /usr/sbin.
Use this function in:
- the 'which' applet
- shellexec(), describe_command() and find_command() in ash
- mingw_spawn_1()
See GitHub issue #195.
Diffstat (limited to 'win32')
-rw-r--r-- | win32/mingw.c | 13 | ||||
-rw-r--r-- | win32/process.c | 15 |
2 files changed, 26 insertions, 2 deletions
diff --git a/win32/mingw.c b/win32/mingw.c index e63ffa0ac..4ffc49e9a 100644 --- a/win32/mingw.c +++ b/win32/mingw.c | |||
@@ -1818,6 +1818,19 @@ void *get_proc_addr(const char *dll, const char *function, | |||
1818 | return proc->pfunction; | 1818 | return proc->pfunction; |
1819 | } | 1819 | } |
1820 | 1820 | ||
1821 | #if ENABLE_FEATURE_SH_STANDALONE || ENABLE_FEATURE_PREFER_APPLETS | ||
1822 | int unix_path(const char *path) | ||
1823 | { | ||
1824 | int i; | ||
1825 | char *p = strdup(path); | ||
1826 | |||
1827 | #define UNIX_PATHS "/bin\0/usr/bin\0/sbin\0/usr/sbin\0" | ||
1828 | i = index_in_strings(UNIX_PATHS, dirname(p)); | ||
1829 | free(p); | ||
1830 | return i >= 0; | ||
1831 | } | ||
1832 | #endif | ||
1833 | |||
1821 | /* Return true if file is referenced using a path. This means a path | 1834 | /* Return true if file is referenced using a path. This means a path |
1822 | * look-up isn't required. */ | 1835 | * look-up isn't required. */ |
1823 | int has_path(const char *file) | 1836 | int has_path(const char *file) |
diff --git a/win32/process.c b/win32/process.c index cd164e0ed..a050ec11d 100644 --- a/win32/process.c +++ b/win32/process.c | |||
@@ -350,6 +350,7 @@ mingw_spawn_1(int mode, const char *cmd, char *const *argv, char *const *envp) | |||
350 | { | 350 | { |
351 | char *prog; | 351 | char *prog; |
352 | const char *path; | 352 | const char *path; |
353 | intptr_t ret; | ||
353 | 354 | ||
354 | #if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_FEATURE_SH_STANDALONE | 355 | #if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_FEATURE_SH_STANDALONE |
355 | if (find_applet_by_name(cmd) >= 0) | 356 | if (find_applet_by_name(cmd) >= 0) |
@@ -357,12 +358,22 @@ mingw_spawn_1(int mode, const char *cmd, char *const *argv, char *const *envp) | |||
357 | else | 358 | else |
358 | #endif | 359 | #endif |
359 | if (has_path(cmd)) { | 360 | if (has_path(cmd)) { |
361 | #if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_FEATURE_SH_STANDALONE | ||
362 | const char *oldcmd = cmd; | ||
363 | #endif | ||
360 | cmd = auto_add_system_drive(cmd); | 364 | cmd = auto_add_system_drive(cmd); |
361 | path = auto_win32_extension(cmd); | 365 | path = auto_win32_extension(cmd); |
362 | return mingw_spawn_interpreter(mode, path ? path : cmd, argv, envp, 0); | 366 | ret = mingw_spawn_interpreter(mode, path ? path : cmd, argv, envp, 0); |
367 | #if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_FEATURE_SH_STANDALONE | ||
368 | if (ret == -1 && cmd != oldcmd && unix_path(oldcmd) && | ||
369 | find_applet_by_name(bb_basename(oldcmd))) { | ||
370 | return mingw_spawn_applet(mode, argv, envp); | ||
371 | } | ||
372 | #endif | ||
373 | return ret; | ||
363 | } | 374 | } |
364 | else if ((prog=find_first_executable(cmd)) != NULL) { | 375 | else if ((prog=find_first_executable(cmd)) != NULL) { |
365 | intptr_t ret = mingw_spawn_interpreter(mode, prog, argv, envp, 0); | 376 | ret = mingw_spawn_interpreter(mode, prog, argv, envp, 0); |
366 | free(prog); | 377 | free(prog); |
367 | return ret; | 378 | return ret; |
368 | } | 379 | } |