aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2024-06-12 12:34:08 +0100
committerRon Yorston <rmy@pobox.com>2024-06-12 12:43:39 +0100
commit2817c3d4f3fb60b6719782cde57a6b7347cf2898 (patch)
tree177dc25062b8eadddc988c638920f417c77bb2b1
parenta518a4f6023582744fa271ec279375dd3d51a4d4 (diff)
downloadbusybox-w32-path_search.tar.gz
busybox-w32-path_search.tar.bz2
busybox-w32-path_search.zip
win32: allow for trailing separator in PATHpath_search
In recent versions of Windows the PATH environment variable has a trailing semicolon. This is insignificant to Windows because it's ignored. busybox-w32 conforms to the POSIX interpretation of PATH which treats an empty path element as denoting the current directory. As result, on these versions of Windows executables may by default be run from the current directory, contrary to usual Unix practice. Attempt to detect and remove the trailing semicolon on applet start up. If the user insists, they can add a trailing semicolon to the shell variable PATH and it will be respected in the conventional manner. Adds 88-112 bytes.
-rw-r--r--include/mingw.h1
-rw-r--r--libbb/appletlib.c12
-rw-r--r--shell/ash.c46
-rw-r--r--win32/mingw.c26
4 files changed, 47 insertions, 38 deletions
diff --git a/include/mingw.h b/include/mingw.h
index 2a6cae4ee..fae732332 100644
--- a/include/mingw.h
+++ b/include/mingw.h
@@ -638,3 +638,4 @@ char *get_user_name(void);
638char *quote_arg(const char *arg); 638char *quote_arg(const char *arg);
639char *find_first_executable(const char *name); 639char *find_first_executable(const char *name);
640char *xappendword(const char *str, const char *word); 640char *xappendword(const char *str, const char *word);
641int windows_env(void);
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index 1232d97c9..1f9968f10 100644
--- a/libbb/appletlib.c
+++ b/libbb/appletlib.c
@@ -1410,6 +1410,18 @@ int main(int argc UNUSED_PARAM, char **argv)
1410 if (s) 1410 if (s)
1411 *s = '\0'; 1411 *s = '\0';
1412 } 1412 }
1413
1414 if (windows_env()) {
1415 /* remove single trailing separator from PATH */
1416 for (char **envp = environ; envp && *envp; envp++) {
1417 if (is_prefixed_with_case(*envp, "PATH=")) {
1418 char *end = last_char_is(*envp, ';');
1419 if (end && end[-1] != ';')
1420 *end = '\0';
1421 break;
1422 }
1423 }
1424 }
1413# endif 1425# endif
1414 applet_name = bb_basename(applet_name); 1426 applet_name = bb_basename(applet_name);
1415 1427
diff --git a/shell/ash.c b/shell/ash.c
index d2c88c4bc..ad77689e7 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -15885,30 +15885,6 @@ static void setvar_if_unset(const char *key, const char *value)
15885} 15885}
15886#endif 15886#endif
15887 15887
15888#if ENABLE_PLATFORM_MINGW32
15889/*
15890 * Detect if the environment contains certain mixed-case names:
15891 *
15892 * Path is present in a standard Windows environment
15893 * ComSpec is present in WINE
15894 * ProgramData is present in Cygwin/MSYS2
15895 */
15896static int mixed_case_special_name(const char *envp)
15897{
15898 const char *names = "PATH=\0""COMSPEC=\0""PROGRAMDATA=\0";
15899 const char *n;
15900
15901 for (n = names; *n; ) {
15902 if (is_prefixed_with_case(envp, n) && !is_prefixed_with(envp, n)) {
15903 return TRUE;
15904 }
15905 while (*n++)
15906 ;
15907 }
15908 return FALSE;
15909}
15910#endif
15911
15912/* Don't inline: conserve stack of caller from having our locals too */ 15888/* Don't inline: conserve stack of caller from having our locals too */
15913static NOINLINE void 15889static NOINLINE void
15914init(void) 15890init(void)
@@ -15941,26 +15917,20 @@ init(void)
15941 * We may end up having both Path and PATH. Then Path will be chosen 15917 * We may end up having both Path and PATH. Then Path will be chosen
15942 * because it appears first. 15918 * because it appears first.
15943 */ 15919 */
15944 for (envp = environ; envp && *envp; envp++) { 15920 if (windows_env()) {
15945 if (mixed_case_special_name(*envp)) {
15946 /* mintty sets HOME: unset it */
15947 const char *tty = getenv("TERM_PROGRAM");
15948 if (tty && strcmp(tty, "mintty") == 0) {
15949 unsetenv("HOME");
15950 }
15951 break;
15952 }
15953 }
15954
15955 if (envp && *envp) {
15956 /* 15921 /*
15957 * If we get here it's because the environment contains a path 15922 * If we get here it's because the environment suggests we
15958 * variable called something other than PATH. This suggests we
15959 * haven't been invoked from an earlier instance of BusyBox. 15923 * haven't been invoked from an earlier instance of BusyBox.
15960 */ 15924 */
15961 char *start, *end; 15925 char *start, *end;
15962 struct passwd *pw; 15926 struct passwd *pw;
15963 15927
15928 /* mintty sets HOME: unset it */
15929 const char *tty = getenv("TERM_PROGRAM");
15930 if (tty && strcmp(tty, "mintty") == 0) {
15931 unsetenv("HOME");
15932 }
15933
15964 import = VIMPORT; 15934 import = VIMPORT;
15965 for (envp = environ; envp && *envp; envp++) { 15935 for (envp = environ; envp && *envp; envp++) {
15966 if (!(end=strchr(*envp, '='))) 15936 if (!(end=strchr(*envp, '=')))
diff --git a/win32/mingw.c b/win32/mingw.c
index d3daf8315..f96b5b49a 100644
--- a/win32/mingw.c
+++ b/win32/mingw.c
@@ -2464,3 +2464,29 @@ char *xappendword(const char *str, const char *word)
2464 free((void *)str); 2464 free((void *)str);
2465 return newstr; 2465 return newstr;
2466} 2466}
2467
2468/*
2469 * Detect if the environment contains certain mixed-case names:
2470 *
2471 * Path is present in a standard Windows environment
2472 * ComSpec is present in WINE
2473 * ProgramData is present in Cygwin/MSYS2
2474 */
2475int
2476windows_env(void)
2477{
2478 const char *names = "PATH=\0""COMSPEC=\0""PROGRAMDATA=\0";
2479 const char *n;
2480
2481 for (char **envp = environ; envp && *envp; envp++) {
2482 for (n = names; *n; ) {
2483 if (is_prefixed_with_case(*envp, n) &&
2484 !is_prefixed_with(*envp, n)) {
2485 return TRUE;
2486 }
2487 while (*n++)
2488 ;
2489 }
2490 }
2491 return FALSE;
2492}