]> sourceware.org Git - newlib-cygwin.git/commitdiff
* cygheap.h (struct cwdstuff): Add dir member to store cwd handle.
authorCorinna Vinschen <corinna@vinschen.de>
Thu, 31 Jan 2008 14:18:49 +0000 (14:18 +0000)
committerCorinna Vinschen <corinna@vinschen.de>
Thu, 31 Jan 2008 14:18:49 +0000 (14:18 +0000)
(cwdstuff::get_handle): New method.
* path.cc (cwdstuff::set): When doit is true, always try to get
directory handle.  Fail if duplicating handle fails.  Store handle
in dir.  Fix potential SEGV when setting drive_length.

winsup/cygwin/ChangeLog
winsup/cygwin/cygheap.h
winsup/cygwin/path.cc

index f88b56212ce3332bf58ed7a62c787e1fc0db95d1..20af6ca600e242f3436f75193731ea2dd9ae04f1 100644 (file)
@@ -1,3 +1,11 @@
+2008-01-31  Corinna Vinschen  <corinna@vinschen.de>
+
+       * cygheap.h (struct cwdstuff): Add dir member to store cwd handle.
+       (cwdstuff::get_handle): New method.
+       * path.cc (cwdstuff::set): When doit is true, always try to get
+       directory handle.  Fail if duplicating handle fails.  Store handle
+       in dir.  Fix potential SEGV when setting drive_length. 
+
 2008-01-28  Corinna Vinschen  <corinna@vinschen.de>
 
        * path.cc: Fix Samba version in comment.
index f51b9a1e9b5b8559754c4a023fdba26d5c1ec3a1..7d232584a9e8c1402dbf4efe1e0a185fad1d19e9 100644 (file)
@@ -223,9 +223,11 @@ struct cwdstuff
 {
   char *posix;
   UNICODE_STRING win32;
+  HANDLE dir;
   DWORD drive_length;
   static muto cwd_lock;
   char *get (char *, int = 1, int = 0, unsigned = CYG_MAX_PATH);
+  HANDLE get_handle () { return dir; }
   DWORD get_drive (char * dst)
   {
     cwd_lock.acquire ();
index a3b0f007eebe13e5c3685d6208cdbbdae4b85099..8d7703e4077df77dbf365dd74089a7eb90e64516 100644 (file)
@@ -4431,7 +4431,7 @@ cwdstuff::set (PUNICODE_STRING nat_cwd, const char *posix_cwd, bool doit)
         - Unlinking a cwd fails because SetCurrentDirectory seems to
           open directories so that deleting the directory is disallowed.
           The below code opens with *all* sharing flags set. */
-      HANDLE h;
+      HANDLE h, h_copy;
       NTSTATUS status;
       IO_STATUS_BLOCK io;
       OBJECT_ATTRIBUTES attr;
@@ -4441,18 +4441,6 @@ cwdstuff::set (PUNICODE_STRING nat_cwd, const char *posix_cwd, bool doit)
       phdl = &get_user_proc_parms ()->CurrentDirectoryHandle;
       if (!nat_cwd) /* On init, just reopen CWD with desired access flags. */
        RtlInitUnicodeString (&upath, L"");
-      else
-       {
-         /* TODO:
-            Check the length of the new CWD.  Windows can only handle
-            CWDs of up to MAX_PATH length, including a trailing backslash.
-            If the path is longer, it's not an error condition for Cygwin,
-            so we don't fail.  Windows on the other hand has a problem now.
-            For now, we just don't store the path in the PEB and proceed as
-            usual. */
-         if (len > MAX_PATH - (nat_cwd->Buffer[len - 1] == L'\\' ? 1 : 2))
-           goto skip_peb_storing;
-       }
       InitializeObjectAttributes (&attr, &upath,
                                  OBJ_CASE_INSENSITIVE | OBJ_INHERIT,
                                  nat_cwd ? NULL : *phdl, NULL);
@@ -4468,8 +4456,36 @@ cwdstuff::set (PUNICODE_STRING nat_cwd, const char *posix_cwd, bool doit)
          res = -1;
          goto out;
        }
+      /* Workaround a problem in Vista which fails in subsequent calls to
+        CreateFile with ERROR_INVALID_HANDLE if the handle in
+        CurrentDirectoryHandle changes without calling SetCurrentDirectory,
+        and the filename given to CreateFile is a relative path.  It looks
+        like Vista stores a copy of the CWD handle in some other undocumented
+        place.  The NtClose/DuplicateHandle reuses the original handle for
+        the copy of the new handle and the next CreateFile works.
+        Note that this is not thread-safe (yet?) */
+      if (!DuplicateHandle (GetCurrentProcess (), h, GetCurrentProcess (),
+                           &h_copy, 0, TRUE, DUPLICATE_SAME_ACCESS))
+       {
+         RtlReleasePebLock ();
+         __seterrno ();
+         NtClose (h);
+         res = -1;
+         goto out;
+       }
+      NtClose (*phdl);
+      dir = *phdl = h;
 
-      if (nat_cwd) /* No need to set path on init. */
+      /* No need to set path on init. */
+      if (nat_cwd
+         /* TODO:
+            Check the length of the new CWD.  Windows can only handle
+            CWDs of up to MAX_PATH length, including a trailing backslash.
+            If the path is longer, it's not an error condition for Cygwin,
+            so we don't fail.  Windows on the other hand has a problem now.
+            For now, we just don't store the path in the PEB and proceed as
+            usual. */
+         && len <= MAX_PATH - (nat_cwd->Buffer[len - 1] == L'\\' ? 1 : 2))
         {
          /* Convert to a Win32 path. */
          upath.Buffer += upath.Length / sizeof (WCHAR) - len;
@@ -4485,22 +4501,6 @@ cwdstuff::set (PUNICODE_STRING nat_cwd, const char *posix_cwd, bool doit)
          RtlCopyUnicodeString (&get_user_proc_parms ()->CurrentDirectoryName,
                                &upath);
        }
-      NtClose (*phdl);
-      /* Workaround a problem in Vista which fails in subsequent calls to
-        CreateFile with ERROR_INVALID_HANDLE if the handle in
-        CurrentDirectoryHandle changes without calling SetCurrentDirectory,
-        and the filename given to CreateFile is a relative path.  It looks
-        like Vista stores a copy of the CWD handle in some other undocumented
-        place.  The NtClose/DuplicateHandle reuses the original handle for
-        the copy of the new handle and the next CreateFile works.
-        Note that this is not thread-safe (yet?) */
-      if (DuplicateHandle (GetCurrentProcess (), h, GetCurrentProcess (), phdl,
-                          0, TRUE, DUPLICATE_SAME_ACCESS))
-       NtClose (h);
-      else
-       *phdl = h;
-
-skip_peb_storing:
 
       RtlReleasePebLock ();
     }
@@ -4552,7 +4552,7 @@ skip_peb_storing:
       else if (win32.Buffer[1] == L'\\')
        {
          PWCHAR ptr = wcschr (win32.Buffer + 2, L'\\');
-         if (*ptr)
+         if (ptr)
            ptr = wcschr (ptr + 1, L'\\');
          if (ptr)
            drive_length = ptr - win32.Buffer;
This page took 0.038252 seconds and 5 git commands to generate.