From b990323902ab8c16d84a45e3ed5b319874320d64 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Tue, 2 Apr 2019 10:17:17 +0100 Subject: win32: try to make working directory names consistent Standardise the path names used for the current working directory by: - resolving with realpath(3); - making the drive name or host name uppercase. The first only really works for physical drives; results for mapped drives are patchy. The standardisation is applied in two places: - at the end of updatepwd() in ash; - when a symbolic link is resolved in mingw_chdir(). --- include/mingw.h | 1 + shell/ash.c | 1 + win32/mingw.c | 27 ++++++++++++++++++++++++++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/include/mingw.h b/include/mingw.h index 1ec5292d8..07f9857e9 100644 --- a/include/mingw.h +++ b/include/mingw.h @@ -530,3 +530,4 @@ char *get_system_drive(void); int chdir_system_drive(void); char *xabsolute_path(char *path); char *get_drive_cwd(const char *path, char *buffer, int size); +void fix_path_case(char *path); diff --git a/shell/ash.c b/shell/ash.c index 68512799e..6bc1dba24 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -2980,6 +2980,7 @@ updatepwd(const char *dir) if (new > lim) STUNPUTC(new); *new = 0; + fix_path_case((char *)stackblock()); return stackblock(); #else char *new; diff --git a/win32/mingw.c b/win32/mingw.c index 22a3ede58..3f80b53f1 100644 --- a/win32/mingw.c +++ b/win32/mingw.c @@ -1208,8 +1208,11 @@ int mingw_chdir(const char *dirname) int ret = -1; const char *realdir = dirname; - if (lstat(dirname, &st) == 0 && S_ISLNK(st.st_mode)) + if (lstat(dirname, &st) == 0 && S_ISLNK(st.st_mode)) { realdir = auto_string(xmalloc_readlink(dirname)); + if (realdir) + fix_path_case((char *)realdir); + } if (realdir) ret = chdir(realdir); @@ -1715,3 +1718,25 @@ char *get_drive_cwd(const char *path, char *buffer, int size) bs_to_slash(buffer); return buffer; } + +void fix_path_case(char *path) +{ + char resolved[PATH_MAX]; + int len; + + // Canonicalise path: for physical drives this makes case match + // what's stored on disk. For mapped drives, not so much. + if (realpath(path, resolved) && strcasecmp(path, resolved) == 0) + strcpy(path, resolved); + + // make drive letter or UNC hostname uppercase + len = root_len(path); + if (len == 2) { + *path = toupper(*path); + } + else if (len != 0) { + for (path+=2; !is_path_sep(*path); ++path) { + *path = toupper(*path); + } + } +} -- cgit v1.2.3-55-g6feb