]> sourceware.org Git - newlib-cygwin.git/commitdiff
* syscalls.cc (unlink_nt): First remove the R/O DOS attribute with
authorCorinna Vinschen <corinna@vinschen.de>
Thu, 16 Jul 2009 16:55:25 +0000 (16:55 +0000)
committerCorinna Vinschen <corinna@vinschen.de>
Thu, 16 Jul 2009 16:55:25 +0000 (16:55 +0000)
FILE_WRITE_ATTRIBUTES access only, then re-open the file for DELETE.
Explain why.

winsup/cygwin/ChangeLog
winsup/cygwin/syscalls.cc

index ec9228aa6fe299e8e13f794f9d58b206daa8500d..3fd808ea8ccf765f4657975d884315c812b42034 100644 (file)
@@ -1,3 +1,9 @@
+2009-07-16  Corinna Vinschen  <corinna@vinschen.de>
+
+       * syscalls.cc (unlink_nt): First remove the R/O DOS attribute with
+       FILE_WRITE_ATTRIBUTES access only, then re-open the file for DELETE.
+       Explain why.
+
 2009-07-16  Corinna Vinschen  <corinna@vinschen.de>
 
        * fhandler_disk_file.cc (fhandler_disk_file::fchmod): Remove file
index 1bb6007f65b8f4eeb8a777f3ee33335bfe5120aa..14dd884b1f4f057f50763538f9dd7459cc4eff29 100644 (file)
@@ -445,17 +445,13 @@ NTSTATUS
 unlink_nt (path_conv &pc)
 {
   NTSTATUS status;
-  HANDLE fh;
+  HANDLE fh, fh_ro = NULL;
   OBJECT_ATTRIBUTES attr;
   IO_STATUS_BLOCK io;
 
-  ACCESS_MASK access = DELETE;
-  /* If the R/O attribute is set, we have to open the file with
-     FILE_WRITE_ATTRIBUTES to be able to remove this flags before trying
-     to delete it. */
-  if (pc.file_attributes () & FILE_ATTRIBUTE_READONLY)
-    access |= FILE_WRITE_ATTRIBUTES;
+  bin_status bin_stat = dont_move;
 
+  ACCESS_MASK access = DELETE;
   ULONG flags = FILE_OPEN_FOR_BACKUP_INTENT;
   /* Add the reparse point flag to native symlinks, otherwise we remove the
      target, not the symlink. */
@@ -463,13 +459,31 @@ unlink_nt (path_conv &pc)
     flags |= FILE_OPEN_REPARSE_POINT;
 
   pc.get_object_attr (attr, sec_none_nih);
+  /* If the R/O attribute is set, we have to open the file with
+     FILE_WRITE_ATTRIBUTES to be able to remove this flags before trying
+     to delete it.  We do this separately because there are filesystems
+     out there (MVFS), which refuse a request to open a file for DELETE
+     if the DOS R/O attribute is set for the file.  After removing the R/O
+     attribute, just re-open the file for DELETE and go ahead. */
+  if (pc.file_attributes () & FILE_ATTRIBUTE_READONLY)
+    {
+      access |= FILE_WRITE_ATTRIBUTES;
+      status = NtOpenFile (&fh_ro, FILE_WRITE_ATTRIBUTES, &attr, &io,
+                          FILE_SHARE_VALID_FLAGS, flags);
+      if (NT_SUCCESS (status))
+       {
+         NtSetAttributesFile (fh_ro, pc.file_attributes ()
+                                     & ~FILE_ATTRIBUTE_READONLY);
+         InitializeObjectAttributes (&attr, &ro_u_empty,
+                                     pc.objcaseinsensitive (), fh_ro, NULL);
+       }
+    }
   /* First try to open the file with only allowing sharing for delete.  If
      the file has an open handle on it, other than just for deletion, this
      will fail.  That indicates that the file has to be moved to the recycle
      bin so that it actually disappears from its directory even though its
      in use.  Otherwise, if opening doesn't fail, the file is not in use and
      we can go straight to setting the delete disposition flag. */
-  bin_status bin_stat = dont_move;
   status = NtOpenFile (&fh, access, &attr, &io, FILE_SHARE_DELETE, flags);
   if (status == STATUS_SHARING_VIOLATION || status == STATUS_LOCK_NOT_GRANTED)
     {
@@ -512,11 +526,15 @@ unlink_nt (path_conv &pc)
              if (!NT_SUCCESS (status))
                {
                  NtClose (fh);
+                 if (fh_ro)
+                   NtClose (fh_ro);
                  return status;
                }
            }
        }
     }
+  if (fh_ro)
+    NtClose (fh_ro);
   if (!NT_SUCCESS (status))
     {
       if (status == STATUS_DELETE_PENDING)
@@ -527,9 +545,6 @@ unlink_nt (path_conv &pc)
       syscall_printf ("Opening file for delete failed, status = %p", status);
       return status;
     }
-  /* Get rid of read-only attribute. */
-  if (access & FILE_WRITE_ATTRIBUTES)
-    NtSetAttributesFile (fh, pc.file_attributes () & ~FILE_ATTRIBUTE_READONLY);
   /* Try to move to bin if a sharing violation occured.  If that worked,
      we're done. */
   if (bin_stat == move_to_bin
This page took 0.037421 seconds and 5 git commands to generate.