From a4563209156b42816f2936374bd09e3bc84837f8 Mon Sep 17 00:00:00 2001
From: Pierre Humblet <phumblet@phumblet.no-ip.org>
Date: Tue, 7 Sep 2004 23:26:28 +0000
Subject: [PATCH] 2004-09-05  Pierre Humblet <pierre.humblet@ieee.org>

        * cygheap.h (cwdstuff::drive_length): New member.
        (cwdstuff::get_drive): New method.
        * path.cc (normalize_win32_path): Simplify by using cwdstuff::get_drive.
        (mount_info::conv_to_win32_path): Use cwdstuff::get_drive as default for /.
        (cwdstuff::set): Initialize drive_length.
---
 winsup/cygwin/ChangeLog |  8 +++++++
 winsup/cygwin/cygheap.h |  7 ++++++
 winsup/cygwin/path.cc   | 49 ++++++++++++++++++++++-------------------
 3 files changed, 41 insertions(+), 23 deletions(-)

diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 0dbabc812..4b565f68d 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,11 @@
+2004-09-08  Pierre Humblet <pierre.humblet@ieee.org>
+
+	* cygheap.h (cwdstuff::drive_length): New member.
+	(cwdstuff::get_drive): New method.
+	* path.cc (normalize_win32_path): Simplify by using cwdstuff::get_drive.
+	(mount_info::conv_to_win32_path): Use cwdstuff::get_drive as default for /.
+	(cwdstuff::set): Initialize drive_length.
+
 2004-09-07  Christopher Faylor  <cgf@timesys.com>
 
 	* cygtls.cc (_cygtls::init_thread): Set __sdidinit to negative value to
diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h
index 59253b5c7..c19a51ae2 100644
--- a/winsup/cygwin/cygheap.h
+++ b/winsup/cygwin/cygheap.h
@@ -216,9 +216,16 @@ struct cwdstuff
   char *posix;
   char *win32;
   DWORD hash;
+  DWORD drive_length;
   muto *cwd_lock;
   char *get (char *, int = 1, int = 0, unsigned = CYG_MAX_PATH);
   DWORD get_hash ();
+  DWORD get_drive (char * dst) 
+  {
+    get_initial (); 
+    memcpy (dst, win32, drive_length); 
+    return drive_length;
+  }
   void init ();
   void fixup_after_exec (char *, char *, DWORD);
   bool get_initial ();
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index d70dd59a9..375ba7ee2 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -980,27 +980,15 @@ normalize_win32_path (const char *src, char *dst, char **tail)
     }
   else if (strchr (src, ':') == NULL && *src != '/')
     {
-      if (!cygheap->cwd.get (dst, 0))
-	return get_errno ();
       if (beg_src_slash)
-	{
-	  if (dst[1] == ':')
-	    dst[2] = '\0';
-	  else if (is_unc_share (dst))
-	    {
-	      char *p = strpbrk (dst + 2, "\\/");
-	      if (p && (p = strpbrk (p + 1, "\\/")))
-		  *p = '\0';
-	    }
-	}
-      if (strlen (dst) + 1 + strlen (src) >= CYG_MAX_PATH)
-	{
-	  debug_printf ("ENAMETOOLONG = normalize_win32_path (%s)", src);
-	  return ENAMETOOLONG;
-	}
-      dst += strlen (dst);
-      if (!beg_src_slash)
-	*dst++ = '\\';
+        dst += cygheap->cwd.get_drive (dst);
+      else if (!cygheap->cwd.get (dst, 0))
+	return get_errno ();
+      else
+        {
+          dst += strlen (dst);
+          *dst++ = '\\';
+        }
     }
 
   while (*src)
@@ -1520,9 +1508,13 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev,
 	return err;
       chroot_ok = true;
     }
-  else
-    backslashify (src_path, dst, 0);
-
+  else 
+    {
+      int offset = 0;
+      if (src_path[1] != '/' && src_path[1] != ':')
+        offset = cygheap->cwd.get_drive (dst);
+      backslashify (src_path, dst + offset, 0);
+    }
  out:
   MALLOC_CHECK;
   if (chroot_ok || cygheap->root.ischroot_native (dst))
@@ -3705,6 +3697,17 @@ cwdstuff::set (const char *win32_cwd, const char *posix_cwd, bool doit)
       win32 = (char *) crealloc (win32, strlen (win32_cwd) + 1);
       strcpy (win32, win32_cwd);
     }
+  if (win32[1] == ':')
+    drive_length = 2;
+  else if (win32[1] == '\\')
+    {
+      char * ptr = strechr (win32 + 2, '\\');
+      if (*ptr)
+	ptr = strechr (ptr + 1, '\\');
+      drive_length = ptr - win32;
+    }
+  else
+    drive_length = 0;
 
   if (!posix_cwd)
     {