aboutsummaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2020-08-13 14:27:56 +0100
committerRon Yorston <rmy@pobox.com>2020-08-13 14:58:01 +0100
commit41ef232fc522d91f29931ea4ee547432ca8899ee (patch)
treed2acfdc43839b68b569debb4494d5c7fbd8bc66b /win32
parent16e5930a65f3c7c570b8a0dda8daa19ab4792fa2 (diff)
downloadbusybox-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.c13
-rw-r--r--win32/process.c15
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
1822int 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. */
1823int has_path(const char *file) 1836int 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 }