aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2023-06-04 08:00:51 +0100
committerRon Yorston <rmy@pobox.com>2023-06-04 08:00:51 +0100
commitbd7018350d7e816a90dde97fa0a4abf41be17b4d (patch)
treef28f42c8139dd1b9aae339ef0c9b69356c6c9acc
parente013876e1dc0ce8e3a36abea9390d35a7053bd84 (diff)
downloadbusybox-w32-bd7018350d7e816a90dde97fa0a4abf41be17b4d.tar.gz
busybox-w32-bd7018350d7e816a90dde97fa0a4abf41be17b4d.tar.bz2
busybox-w32-bd7018350d7e816a90dde97fa0a4abf41be17b4d.zip
win32: another BB_OVERRIDE_APPLETS fix
Support for conditionally replacing applets with external commands requires the ability to check whether a given command name is present on PATH. This was being done using the PATH environment variable, which works in commands run by the shell but not in the shell itself. - The shell uses the *shell* variable PATH to look for executables. This may not be the same as the *environment* variable. - 'command -p' uses an entirely different PATH. Applet look-up in the shell is now treated as a special case, with the actual PATH being used passed to the look-up code in a global variable. This doesn't affect tab completion in the shell: whether a completion is an applet or an external command is irrelevant. Costs 152-288 bytes. (GitHub issue #329)
-rw-r--r--include/libbb.h3
-rw-r--r--libbb/appletlib.c9
-rw-r--r--shell/ash.c42
3 files changed, 48 insertions, 6 deletions
diff --git a/include/libbb.h b/include/libbb.h
index a4eebab99..1200e636a 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1330,6 +1330,9 @@ int find_preferred_applet_by_name(const char *name) FAST_FUNC;
1330int is_applet_preferred(const char *name) FAST_FUNC; 1330int is_applet_preferred(const char *name) FAST_FUNC;
1331# if ENABLE_PLATFORM_MINGW32 && \ 1331# if ENABLE_PLATFORM_MINGW32 && \
1332 (ENABLE_FEATURE_PREFER_APPLETS || ENABLE_FEATURE_SH_STANDALONE) 1332 (ENABLE_FEATURE_PREFER_APPLETS || ENABLE_FEATURE_SH_STANDALONE)
1333# if ENABLE_ASH
1334extern const char *ash_path;
1335# endif
1333# define find_applet_by_name(n) find_preferred_applet_by_name(n) 1336# define find_applet_by_name(n) find_preferred_applet_by_name(n)
1334# else 1337# else
1335# define is_applet_preferred(n) (1) 1338# define is_applet_preferred(n) (1)
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index b5ea90ffd..10268b982 100644
--- a/libbb/appletlib.c
+++ b/libbb/appletlib.c
@@ -263,9 +263,16 @@ int FAST_FUNC find_applet_by_name(const char *name)
263 263
264#if ENABLE_PLATFORM_MINGW32 && NUM_APPLETS > 1 && \ 264#if ENABLE_PLATFORM_MINGW32 && NUM_APPLETS > 1 && \
265 (ENABLE_FEATURE_PREFER_APPLETS || ENABLE_FEATURE_SH_STANDALONE) 265 (ENABLE_FEATURE_PREFER_APPLETS || ENABLE_FEATURE_SH_STANDALONE)
266# if ENABLE_ASH
267const char *ash_path = NULL;
268# else
269# define ash_path NULL
270# endif
271
266static int external_exists(const char *name) 272static int external_exists(const char *name)
267{ 273{
268 char *ret = find_first_executable(name); 274 char *path = ash_path ? auto_string(xstrdup(ash_path)) : getenv("PATH");
275 char *ret = find_executable(name, &path);
269 free(ret); 276 free(ret);
270 return ret != NULL; 277 return ret != NULL;
271} 278}
diff --git a/shell/ash.c b/shell/ash.c
index 07319dbdf..7fa75721e 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -426,6 +426,38 @@ static void forkshell_print(FILE *fp0, struct forkshell *fs, const char **notes)
426# endif 426# endif
427#endif 427#endif
428 428
429#if ENABLE_PLATFORM_MINGW32 && NUM_APPLETS > 1 && \
430 (ENABLE_FEATURE_PREFER_APPLETS || ENABLE_FEATURE_SH_STANDALONE)
431static int
432ash_preferred_applet_by_name(const char *name, const char *path)
433{
434 int ret;
435
436 ash_path = path;
437 ret = find_preferred_applet_by_name(name);
438 ash_path = NULL;
439
440 return ret;
441}
442
443static int
444ash_applet_preferred(const char *name, const char *path)
445{
446 int ret;
447
448 ash_path = path;
449 ret = is_applet_preferred(name);
450 ash_path = NULL;
451
452 return ret;
453}
454# undef find_applet_by_name
455# define find_applet_by_name(n, p) ash_preferred_applet_by_name(n, p)
456# define is_applet_preferred(n, p) ash_applet_preferred(n, p)
457#else
458# define find_applet_by_name(n, p) find_applet_by_name(n)
459#endif
460
429/* ============ Hash table sizes. Configurable. */ 461/* ============ Hash table sizes. Configurable. */
430 462
431#define VTABSIZE 39 463#define VTABSIZE 39
@@ -9113,7 +9145,7 @@ static void shellexec(char *prog, char **argv, const char *path, int idx)
9113 if (has_path(prog) 9145 if (has_path(prog)
9114#endif 9146#endif
9115#if ENABLE_FEATURE_SH_STANDALONE 9147#if ENABLE_FEATURE_SH_STANDALONE
9116 || (applet_no = find_applet_by_name(prog)) >= 0 9148 || (applet_no = find_applet_by_name(prog, path)) >= 0
9117#endif 9149#endif
9118 ) { 9150 ) {
9119#if ENABLE_PLATFORM_MINGW32 9151#if ENABLE_PLATFORM_MINGW32
@@ -9134,7 +9166,7 @@ static void shellexec(char *prog, char **argv, const char *path, int idx)
9134 if (unix_path(prog)) { 9166 if (unix_path(prog)) {
9135 const char *name = bb_basename(prog); 9167 const char *name = bb_basename(prog);
9136# if ENABLE_FEATURE_SH_STANDALONE 9168# if ENABLE_FEATURE_SH_STANDALONE
9137 if ((applet_no = find_applet_by_name(name)) >= 0) { 9169 if ((applet_no = find_applet_by_name(name, path)) >= 0) {
9138 tryexec(applet_no, name, argv, envp); 9170 tryexec(applet_no, name, argv, envp);
9139 e = errno; 9171 e = errno;
9140 } 9172 }
@@ -14939,7 +14971,7 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path)
14939 name = (char *)bb_basename(name); 14971 name = (char *)bb_basename(name);
14940 if ( 14972 if (
14941# if ENABLE_FEATURE_SH_STANDALONE 14973# if ENABLE_FEATURE_SH_STANDALONE
14942 find_applet_by_name(name) >= 0 || 14974 find_applet_by_name(name, path) >= 0 ||
14943# endif 14975# endif
14944 !find_builtin(bb_basename(name)) 14976 !find_builtin(bb_basename(name))
14945 ) { 14977 ) {
@@ -15010,7 +15042,7 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path)
15010 15042
15011#if ENABLE_FEATURE_SH_STANDALONE 15043#if ENABLE_FEATURE_SH_STANDALONE
15012 { 15044 {
15013 int applet_no = find_applet_by_name(name); 15045 int applet_no = find_applet_by_name(name, path);
15014 if (applet_no >= 0) { 15046 if (applet_no >= 0) {
15015 entry->cmdtype = CMDNORMAL; 15047 entry->cmdtype = CMDNORMAL;
15016 entry->u.index = -2 - applet_no; 15048 entry->u.index = -2 - applet_no;
@@ -15259,7 +15291,7 @@ helpcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
15259 { 15291 {
15260 const char *a = applet_names; 15292 const char *a = applet_names;
15261 while (*a) { 15293 while (*a) {
15262 if (is_applet_preferred(a)) { 15294 if (is_applet_preferred(a, pathval())) {
15263 col += out1fmt("%c%s", ((col == 0) ? '\t' : ' '), a); 15295 col += out1fmt("%c%s", ((col == 0) ? '\t' : ' '), a);
15264 if (col > 60) { 15296 if (col > 60) {
15265 out1fmt("\n"); 15297 out1fmt("\n");