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. --- win32/mingw.c | 15 +++++++++++++++ win32/process.c | 11 ++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) (limited to 'win32') diff --git a/win32/mingw.c b/win32/mingw.c index 8501ecdd4..e63ffa0ac 100644 --- a/win32/mingw.c +++ b/win32/mingw.c @@ -1698,6 +1698,21 @@ const char *get_system_drive(void) return drive; } +/* Return pointer to system drive if path is of form '/file', else NULL */ +const char *need_system_drive(const char *path) +{ + if (root_len(path) == 0 && (path[0] == '/' || path[0] == '\\')) + return get_system_drive(); + return NULL; +} + +/* Add a system drive prefix to 'path' if necessary, else return 'path' */ +char *auto_add_system_drive(const char *path) +{ + const char *sd = need_system_drive(path); + return sd ? auto_string(concat_path_file(sd, path)) : (char *)path; +} + int chdir_system_drive(void) { const char *sd = get_system_drive(); diff --git a/win32/process.c b/win32/process.c index 1118eb18a..cd164e0ed 100644 --- a/win32/process.c +++ b/win32/process.c @@ -63,6 +63,7 @@ static int parse_interpreter(const char *cmd, interp_t *interp) { char *path, *t; + const char *sd; int n; while (TRUE) { @@ -88,6 +89,12 @@ parse_interpreter(const char *cmd, interp_t *interp) if (*t == '\0') break; + sd = need_system_drive(path); + if (sd && strlen(sd) == 2) { + path -= 2; + memcpy(path, sd, 2); + } + interp->path = path; interp->name = t; interp->opts = strtok(NULL, "\r\n"); @@ -342,6 +349,7 @@ static intptr_t mingw_spawn_1(int mode, const char *cmd, char *const *argv, char *const *envp) { char *prog; + const char *path; #if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_FEATURE_SH_STANDALONE if (find_applet_by_name(cmd) >= 0) @@ -349,7 +357,8 @@ mingw_spawn_1(int mode, const char *cmd, char *const *argv, char *const *envp) else #endif if (has_path(cmd)) { - const char *path = auto_win32_extension(cmd); + cmd = auto_add_system_drive(cmd); + path = auto_win32_extension(cmd); return mingw_spawn_interpreter(mode, path ? path : cmd, argv, envp, 0); } else if ((prog=find_first_executable(cmd)) != NULL) { -- cgit v1.2.3-55-g6feb