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 | ||
