diff options
Diffstat (limited to 'winsup/cygwin/path.cc')
-rw-r--r-- | winsup/cygwin/path.cc | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 6fb228b6d..98e6d5744 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -1408,8 +1408,34 @@ normalize_win32_path (const char *src, char *dst, char *&tail) if (tail == dst) { if (isdrive (src)) - /* Always convert drive letter to uppercase for case sensitivity. */ - *tail++ = cyg_toupper (*src++); + { + /* Drive followed by separator is an absolute path */ + if (isdirsep (src[2])) + /* Always convert drive letter to uppercase for case sensitivity. */ + *tail++ = cyg_toupper (*src++); + else + { + /* Drive-relative path: get drive path from environment. */ + char env[] = { '!', cyg_toupper (*src), ':', 0 }; + const char *drvpath = getenv(env); + + if (drvpath) + { + size_t len = strlcpy(tail, drvpath, NT_MAX_PATH); + + if (len >= NT_MAX_PATH - 1) + return ENAMETOOLONG; + + tail += len; + *tail++ = '\\'; + src += 2; + } + else + { + *tail++ = cyg_toupper (*src++); + } + } + } else { if (beg_src_slash) @@ -4435,6 +4461,20 @@ cwdstuff::override_win32_cwd (bool init, ULONG old_dismount_count) from the parent process. We always have to close it here. */ NtClose (h); } + + /* Simulate the SetCurrentDirectory effect of associating a drive + with its own current directory. This behavior dating all the way + back to MS-DOS is done in Windows with special environment + variables. */ + if (iswdrive (win32.Buffer)) { + tmp_pathbuf tp; + char env[] = { '!', (char) win32.Buffer[0], ':', 0 }; + char *cwdcopy = tp.c_get (); + + sys_wcstombs (cwdcopy, NT_MAX_PATH, win32.Buffer, + win32.Length / sizeof (WCHAR)); + setenv(env, cwdcopy, 1); + } } /* Initialize cygcwd 'muto' for serializing access to cwd info. */ |