diff options
| author | Ron Yorston <rmy@pobox.com> | 2022-05-01 10:20:16 +0100 |
|---|---|---|
| committer | Ron Yorston <rmy@pobox.com> | 2022-05-01 11:03:10 +0100 |
| commit | 6d87be4d760ceda18d354c6d4c523a9adf50c04b (patch) | |
| tree | ca286c74b3d0689591ce7bee6a9b98af93e15e21 /debianutils | |
| parent | ae61e126ee8e8200e87f285d9c410eb377505578 (diff) | |
| download | busybox-w32-6d87be4d760ceda18d354c6d4c523a9adf50c04b.tar.gz busybox-w32-6d87be4d760ceda18d354c6d4c523a9adf50c04b.tar.bz2 busybox-w32-6d87be4d760ceda18d354c6d4c523a9adf50c04b.zip | |
which,ash: changes to which/command/type
Change how 'which' detects if it was run from a standalone shell:
the shell passes the undocumented '-s' option. This is stricter
and more reliable than the previous method of checking the name
of the binary.
Add a function to determine the binary associated with a given
applet name. This makes it possible for 'which' and 'command -v'
to list the correct binary even for applets other than 'busybox'.
For example, when the binary is called 'sh.exe' 'which sh' will
report its path.
In standalone shell mode 'command -V' and 'type' now report "xxx
is a builtin applet" rather than "xxx is xxx", which is true but
not very illuminating.
(GitHub issue #248)
Diffstat (limited to 'debianutils')
| -rw-r--r-- | debianutils/which.c | 50 |
1 files changed, 29 insertions, 21 deletions
diff --git a/debianutils/which.c b/debianutils/which.c index 815ac71da..d00b92e0b 100644 --- a/debianutils/which.c +++ b/debianutils/which.c | |||
| @@ -12,7 +12,12 @@ | |||
| 12 | //config: which is used to find programs in your PATH and | 12 | //config: which is used to find programs in your PATH and |
| 13 | //config: print out their pathnames. | 13 | //config: print out their pathnames. |
| 14 | 14 | ||
| 15 | //applet:IF_WHICH(APPLET_NOFORK(which, which, BB_DIR_USR_BIN, BB_SUID_DROP, which)) | 15 | // NOTE: For WIN32 this applet is NOEXEC as alloc_system_drive() and |
| 16 | // find_executable() both allocate memory. And find_executable() | ||
| 17 | // calls alloc_system_drive(). | ||
| 18 | |||
| 19 | //applet:IF_PLATFORM_MINGW32(IF_WHICH(APPLET_NOEXEC(which, which, BB_DIR_USR_BIN, BB_SUID_DROP, which))) | ||
| 20 | //applet:IF_PLATFORM_POSIX(IF_WHICH(APPLET_NOFORK(which, which, BB_DIR_USR_BIN, BB_SUID_DROP, which))) | ||
| 16 | 21 | ||
| 17 | //kbuild:lib-$(CONFIG_WHICH) += which.o | 22 | //kbuild:lib-$(CONFIG_WHICH) += which.o |
| 18 | 23 | ||
| @@ -28,6 +33,13 @@ | |||
| 28 | 33 | ||
| 29 | #include "libbb.h" | 34 | #include "libbb.h" |
| 30 | 35 | ||
| 36 | #if ENABLE_PLATFORM_MINGW32 && ENABLE_FEATURE_SH_STANDALONE | ||
| 37 | enum { | ||
| 38 | OPT_a = (1 << 0), | ||
| 39 | OPT_s = (1 << 1) | ||
| 40 | }; | ||
| 41 | #endif | ||
| 42 | |||
| 31 | int which_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 43 | int which_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
| 32 | int which_main(int argc UNUSED_PARAM, char **argv) | 44 | int which_main(int argc UNUSED_PARAM, char **argv) |
| 33 | { | 45 | { |
| @@ -36,9 +48,7 @@ int which_main(int argc UNUSED_PARAM, char **argv) | |||
| 36 | /* This sizeof(): bb_default_root_path is shorter than BB_PATH_ROOT_PATH */ | 48 | /* This sizeof(): bb_default_root_path is shorter than BB_PATH_ROOT_PATH */ |
| 37 | char buf[sizeof(BB_PATH_ROOT_PATH)]; | 49 | char buf[sizeof(BB_PATH_ROOT_PATH)]; |
| 38 | #if ENABLE_PLATFORM_MINGW32 && ENABLE_FEATURE_SH_STANDALONE | 50 | #if ENABLE_PLATFORM_MINGW32 && ENABLE_FEATURE_SH_STANDALONE |
| 39 | /* If we were run as 'which.exe' skip standalone shell behaviour */ | 51 | int sh_standalone; |
| 40 | int sh_standalone = | ||
| 41 | is_suffixed_with_case(bb_busybox_exec_path, "which.exe") == NULL; | ||
| 42 | #endif | 52 | #endif |
| 43 | 53 | ||
| 44 | env_path = getenv("PATH"); | 54 | env_path = getenv("PATH"); |
| @@ -46,28 +56,25 @@ int which_main(int argc UNUSED_PARAM, char **argv) | |||
| 46 | /* env_path must be writable, and must not alloc, so... */ | 56 | /* env_path must be writable, and must not alloc, so... */ |
| 47 | env_path = strcpy(buf, bb_default_root_path); | 57 | env_path = strcpy(buf, bb_default_root_path); |
| 48 | 58 | ||
| 59 | #if ENABLE_PLATFORM_MINGW32 && ENABLE_FEATURE_SH_STANDALONE | ||
| 60 | /* '-s' option indicates we were run from a standalone shell */ | ||
| 61 | getopt32(argv, "^" "as" "\0" "-1"/*at least one arg*/); | ||
| 62 | sh_standalone = option_mask32 & OPT_s; | ||
| 63 | option_mask32 &= ~OPT_s; | ||
| 64 | #else | ||
| 49 | getopt32(argv, "^" "a" "\0" "-1"/*at least one arg*/); | 65 | getopt32(argv, "^" "a" "\0" "-1"/*at least one arg*/); |
| 66 | #endif | ||
| 50 | argv += optind; | 67 | argv += optind; |
| 51 | 68 | ||
| 52 | do { | 69 | do { |
| 53 | int missing = 1; | 70 | int missing = 1; |
| 54 | 71 | ||
| 55 | #if ENABLE_PLATFORM_MINGW32 && ENABLE_FEATURE_SH_STANDALONE | 72 | #if ENABLE_PLATFORM_MINGW32 && ENABLE_FEATURE_SH_STANDALONE |
| 56 | if (sh_standalone) { | 73 | if (sh_standalone && find_applet_by_name(*argv) >= 0) { |
| 57 | if (strcmp(*argv, "busybox") == 0 && | 74 | missing = 0; |
| 58 | is_prefixed_with_case(bb_basename(bb_busybox_exec_path), | 75 | puts(applet_to_exe(*argv)); |
| 59 | "busybox")) { | 76 | if (!option_mask32) /* -a not set */ |
| 60 | missing = 0; | 77 | break; |
| 61 | puts(bb_busybox_exec_path); | ||
| 62 | if (!option_mask32) /* -a not set */ | ||
| 63 | break; | ||
| 64 | } | ||
| 65 | else if (find_applet_by_name(*argv) >= 0) { | ||
| 66 | missing = 0; | ||
| 67 | puts(*argv); | ||
| 68 | if (!option_mask32) /* -a not set */ | ||
| 69 | break; | ||
| 70 | } | ||
| 71 | } | 78 | } |
| 72 | #endif | 79 | #endif |
| 73 | 80 | ||
| @@ -87,15 +94,16 @@ int which_main(int argc UNUSED_PARAM, char **argv) | |||
| 87 | puts(bs_to_slash(path)); | 94 | puts(bs_to_slash(path)); |
| 88 | } | 95 | } |
| 89 | # if ENABLE_FEATURE_SH_STANDALONE | 96 | # if ENABLE_FEATURE_SH_STANDALONE |
| 90 | else if (sh_standalone) { | 97 | else if (sh_standalone && unix_path(*argv)) { |
| 91 | const char *name = bb_basename(*argv); | 98 | const char *name = bb_basename(*argv); |
| 92 | 99 | ||
| 93 | if (unix_path(*argv) && find_applet_by_name(name) >= 0) { | 100 | if (find_applet_by_name(name) >= 0) { |
| 94 | missing = 0; | 101 | missing = 0; |
| 95 | puts(name); | 102 | puts(name); |
| 96 | } | 103 | } |
| 97 | } | 104 | } |
| 98 | # endif | 105 | # endif |
| 106 | free(path); | ||
| 99 | #endif | 107 | #endif |
| 100 | } else { | 108 | } else { |
| 101 | char *path; | 109 | char *path; |
