aboutsummaryrefslogtreecommitdiff
path: root/shell
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 /shell
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 'shell')
-rw-r--r--shell/ash.c55
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