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. --- shell/ash.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index 7a2d0ab68..0a638b1df 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -2828,6 +2828,10 @@ padvance_magic(const char **path, const char *name, int magic) const char *start; size_t qlen; size_t len; +#if ENABLE_PLATFORM_MINGW32 + size_t sdlen = 0; + const char *sd; +#endif if (*path == NULL) return -1; @@ -2859,11 +2863,20 @@ padvance_magic(const char **path, const char *name, int magic) *path = *p == PATH_SEP ? p + 1 : NULL; /* "2" is for '/' and '\0' */ - /* reserve space for suffix on WIN32 */ - qlen = len + strlen(name) + 2 IF_PLATFORM_MINGW32(+ 4); + qlen = len + strlen(name) + 2; +#if ENABLE_PLATFORM_MINGW32 + /* reserve space for system drive prefix and extension */ + sd = need_system_drive(start); + if (sd != NULL) + sdlen = strlen(sd); + qlen += 4 + sdlen; +#endif q = growstackto(qlen); if (len) { +#if ENABLE_PLATFORM_MINGW32 + q = mempcpy(q, sd, sdlen); +#endif q = mempcpy(q, start, len); #if ENABLE_PLATFORM_MINGW32 if (q[-1] != '/' && q[-1] != '\\') @@ -8740,6 +8753,9 @@ static void shellexec(char *prog, char **argv, const char *path, int idx) || (applet_no = find_applet_by_name(prog)) >= 0 #endif ) { +#if ENABLE_PLATFORM_MINGW32 + prog = auto_add_system_drive(prog); +#endif tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) prog, argv, envp); if (applet_no >= 0) { /* We tried execing ourself, but it didn't work. @@ -9176,7 +9192,16 @@ describe_command(char *command, const char *path, int describe_command_verbose) int j = entry.u.index; char *p; if (j < 0) { +#if ENABLE_PLATFORM_MINGW32 + /* can't use auto_add_system_drive, need space for extension */ + const char *sd = need_system_drive(command); + size_t len = strlen(command) + 5 + (sd ? strlen(sd) : 0); + + p = auto_string(xmalloc(len)); + sprintf(p, "%s%s", sd ? sd : "", command); +#else p = command; +#endif } else { do { padvance(&path, command); @@ -14246,6 +14271,7 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path) /* If name contains a slash, don't use PATH or hash table */ #if ENABLE_PLATFORM_MINGW32 if (has_path(name)) { + name = auto_add_system_drive(name); #else if (strchr(name, '/') != NULL) { #endif -- cgit v1.2.3-55-g6feb