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 /shell | |
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 'shell')
-rw-r--r-- | shell/ash.c | 55 |
1 files changed, 46 insertions, 9 deletions
diff --git a/shell/ash.c b/shell/ash.c index 0a638b1df..2267e841f 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -8754,6 +8754,9 @@ static void shellexec(char *prog, char **argv, const char *path, int idx) | |||
8754 | #endif | 8754 | #endif |
8755 | ) { | 8755 | ) { |
8756 | #if ENABLE_PLATFORM_MINGW32 | 8756 | #if ENABLE_PLATFORM_MINGW32 |
8757 | # if ENABLE_FEATURE_SH_STANDALONE | ||
8758 | char *oldprog = prog; | ||
8759 | # endif | ||
8757 | prog = auto_add_system_drive(prog); | 8760 | prog = auto_add_system_drive(prog); |
8758 | #endif | 8761 | #endif |
8759 | tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) prog, argv, envp); | 8762 | tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) prog, argv, envp); |
@@ -8764,6 +8767,14 @@ static void shellexec(char *prog, char **argv, const char *path, int idx) | |||
8764 | */ | 8767 | */ |
8765 | goto try_PATH; | 8768 | goto try_PATH; |
8766 | } | 8769 | } |
8770 | #if ENABLE_PLATFORM_MINGW32 && ENABLE_FEATURE_SH_STANDALONE | ||
8771 | if (oldprog != prog && unix_path(oldprog)) { | ||
8772 | if ((applet_no = find_applet_by_name(bb_basename(oldprog))) >= 0) | ||
8773 | tryexec(applet_no, bb_basename(oldprog), argv, envp); | ||
8774 | else | ||
8775 | errno = ENOENT; | ||
8776 | } | ||
8777 | #endif | ||
8767 | e = errno; | 8778 | e = errno; |
8768 | } else { | 8779 | } else { |
8769 | try_PATH: | 8780 | try_PATH: |
@@ -9191,6 +9202,12 @@ describe_command(char *command, const char *path, int describe_command_verbose) | |||
9191 | case CMDNORMAL: { | 9202 | case CMDNORMAL: { |
9192 | int j = entry.u.index; | 9203 | int j = entry.u.index; |
9193 | char *p; | 9204 | char *p; |
9205 | #if ENABLE_PLATFORM_MINGW32 && ENABLE_FEATURE_SH_STANDALONE | ||
9206 | if (j == INT_MIN) { | ||
9207 | p = (char *)bb_basename(command); | ||
9208 | goto describe; | ||
9209 | } | ||
9210 | #endif | ||
9194 | if (j < 0) { | 9211 | if (j < 0) { |
9195 | #if ENABLE_PLATFORM_MINGW32 | 9212 | #if ENABLE_PLATFORM_MINGW32 |
9196 | /* can't use auto_add_system_drive, need space for extension */ | 9213 | /* can't use auto_add_system_drive, need space for extension */ |
@@ -9211,6 +9228,7 @@ describe_command(char *command, const char *path, int describe_command_verbose) | |||
9211 | #if ENABLE_PLATFORM_MINGW32 | 9228 | #if ENABLE_PLATFORM_MINGW32 |
9212 | add_win32_extension(p); | 9229 | add_win32_extension(p); |
9213 | bs_to_slash(p); | 9230 | bs_to_slash(p); |
9231 | IF_FEATURE_SH_STANDALONE(describe:) | ||
9214 | #endif | 9232 | #endif |
9215 | if (describe_command_verbose) { | 9233 | if (describe_command_verbose) { |
9216 | out1fmt(" is %s", p); | 9234 | out1fmt(" is %s", p); |
@@ -14268,24 +14286,16 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path) | |||
14268 | struct builtincmd *bcmd; | 14286 | struct builtincmd *bcmd; |
14269 | int len; | 14287 | int len; |
14270 | 14288 | ||
14289 | #if !ENABLE_PLATFORM_MINGW32 | ||
14271 | /* If name contains a slash, don't use PATH or hash table */ | 14290 | /* If name contains a slash, don't use PATH or hash table */ |
14272 | #if ENABLE_PLATFORM_MINGW32 | ||
14273 | if (has_path(name)) { | ||
14274 | name = auto_add_system_drive(name); | ||
14275 | #else | ||
14276 | if (strchr(name, '/') != NULL) { | 14291 | if (strchr(name, '/') != NULL) { |
14277 | #endif | ||
14278 | entry->u.index = -1; | 14292 | entry->u.index = -1; |
14279 | if (act & DO_ABS) { | 14293 | if (act & DO_ABS) { |
14280 | #if ENABLE_PLATFORM_MINGW32 | ||
14281 | if (auto_win32_extension(name) == NULL && stat(name, &statb) < 0) { | ||
14282 | #else | ||
14283 | while (stat(name, &statb) < 0) { | 14294 | while (stat(name, &statb) < 0) { |
14284 | #ifdef SYSV | 14295 | #ifdef SYSV |
14285 | if (errno == EINTR) | 14296 | if (errno == EINTR) |
14286 | continue; | 14297 | continue; |
14287 | #endif | 14298 | #endif |
14288 | #endif | ||
14289 | entry->cmdtype = CMDUNKNOWN; | 14299 | entry->cmdtype = CMDUNKNOWN; |
14290 | return; | 14300 | return; |
14291 | } | 14301 | } |
@@ -14293,6 +14303,33 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path) | |||
14293 | entry->cmdtype = CMDNORMAL; | 14303 | entry->cmdtype = CMDNORMAL; |
14294 | return; | 14304 | return; |
14295 | } | 14305 | } |
14306 | #else /* ENABLE_PLATFORM_MINGW32 */ | ||
14307 | /* If name contains a slash or drive prefix, don't use PATH or hash table */ | ||
14308 | if (has_path(name)) { | ||
14309 | # if ENABLE_FEATURE_SH_STANDALONE | ||
14310 | char *oldname = name; | ||
14311 | # endif | ||
14312 | name = auto_add_system_drive(name); | ||
14313 | entry->u.index = -1; | ||
14314 | if (act & DO_ABS) { | ||
14315 | if (auto_win32_extension(name) == NULL && stat(name, &statb) < 0) { | ||
14316 | # if ENABLE_FEATURE_SH_STANDALONE | ||
14317 | int applet_no; | ||
14318 | if (unix_path(oldname) && | ||
14319 | (applet_no = find_applet_by_name(bb_basename(oldname))) >= 0) { | ||
14320 | entry->cmdtype = CMDNORMAL; | ||
14321 | entry->u.index = INT_MIN; | ||
14322 | return; | ||
14323 | } | ||
14324 | # endif | ||
14325 | entry->cmdtype = CMDUNKNOWN; | ||
14326 | return; | ||
14327 | } | ||
14328 | } | ||
14329 | entry->cmdtype = CMDNORMAL; | ||
14330 | return; | ||
14331 | } | ||
14332 | #endif /* ENABLE_PLATFORM_MINGW32 */ | ||
14296 | 14333 | ||
14297 | /* #if ENABLE_FEATURE_SH_STANDALONE... moved after builtin check */ | 14334 | /* #if ENABLE_FEATURE_SH_STANDALONE... moved after builtin check */ |
14298 | 14335 | ||