From 6059723900f2af1fbd394c457d1feae342e344f6 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Thu, 13 Aug 2020 13:56:17 +0100 Subject: win32: handle Unix-style absolute paths for executables As noted in commit 548ec7045 (win32: interpret absolute paths as relative to %SYSTEMDRIVE%) a path starting with a '/' in the Unix world is treated as relative to the current drive by Windows. To avoid ambiguity that commit considered certain such paths to be relative to %SYSTEMDRIVE%. Extend this to paths representing executables. Add the functions need_system_drive() and auto_add_system_drive() to detect the need for a system drive prefix and to add it if necessary. Use these functions in: - the 'which' applet - the find_executable() function - tab-completion code - PATH look-up, shellexec(), describe_command() and find_command() in ash - parse_interpreter() and mingw_spawn_1() With these changes executable paths starting with a slash are handled consistently, whatever the current drive. --- libbb/executable.c | 3 +++ libbb/lineedit.c | 10 +++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'libbb') diff --git a/libbb/executable.c b/libbb/executable.c index 87a40eeda..0a0769ef3 100644 --- a/libbb/executable.c +++ b/libbb/executable.c @@ -49,6 +49,9 @@ char* FAST_FUNC find_executable(const char *filename, char **PATHp) n = strchr(p, PATH_SEP); if (n) *n = '\0'; +#if ENABLE_PLATFORM_MINGW32 + p = auto_add_system_drive(p); +#endif p = concat_path_file( p[0] ? p : ".", /* handle "::" case */ filename diff --git a/libbb/lineedit.c b/libbb/lineedit.c index a36a1647d..f6577e372 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c @@ -913,8 +913,12 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type) struct dirent *next; struct stat st; char *found; - +#if ENABLE_PLATFORM_MINGW32 + char *lpath = auto_add_system_drive(paths[i]); + dir = opendir(lpath); +#else dir = opendir(paths[i]); +#endif if (!dir) continue; /* don't print an error */ @@ -929,7 +933,11 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type) if (!is_prefixed_with(name_found, pfind)) continue; /* no */ +#if ENABLE_PLATFORM_MINGW32 + found = concat_path_file(lpath, name_found); +#else found = concat_path_file(paths[i], name_found); +#endif /* NB: stat() first so that we see is it a directory; * but if that fails, use lstat() so that * we still match dangling links */ -- cgit v1.2.3-55-g6feb