summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/path.cc
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/path.cc')
-rw-r--r--winsup/cygwin/path.cc44
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. */