aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2009-01-07 18:18:23 +0000
committerCorinna Vinschen <corinna@vinschen.de>2009-01-07 18:18:23 +0000
commitf4ad04049fcd12246bc26e7de1adf948037e60e0 (patch)
treeb4351b10b1f67c9d3609a890b43be53cdd4486ee
parent3bee7767a8437f9e555791c0fa01d97cf48bc35b (diff)
downloadnewlib-f4ad04049fcd12246bc26e7de1adf948037e60e0.zip
newlib-f4ad04049fcd12246bc26e7de1adf948037e60e0.tar.gz
newlib-f4ad04049fcd12246bc26e7de1adf948037e60e0.tar.bz2
* ntdll.h: Reorder NT status flags. Fix a case difference. Add
STATUS_CANNOT_DELETE flag. * syscalls.cc (unlink_nt): Change initial NtOpenFile to request FILE_SHARE_DELETE sharing mode. Change comment accordingly. If setting delete disposition failed with STATUS_CANNOT_DELETE, try to delete using delete-on-close. Explain why. Rearrange setting R/O DOS attribute after trying to delete. Simplify comment.
-rw-r--r--winsup/cygwin/ChangeLog11
-rw-r--r--winsup/cygwin/ntdll.h5
-rw-r--r--winsup/cygwin/syscalls.cc56
3 files changed, 57 insertions, 15 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 2faa2e5..6753d2a 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,16 @@
2009-01-07 Corinna Vinschen <corinna@vinschen.de>
+ * ntdll.h: Reorder NT status flags. Fix a case difference. Add
+ STATUS_CANNOT_DELETE flag.
+ * syscalls.cc (unlink_nt): Change initial NtOpenFile to request
+ FILE_SHARE_DELETE sharing mode. Change comment accordingly.
+ If setting delete disposition failed with STATUS_CANNOT_DELETE, try
+ to delete using delete-on-close. Explain why.
+ Rearrange setting R/O DOS attribute after trying to delete. Simplify
+ comment.
+
+2009-01-07 Corinna Vinschen <corinna@vinschen.de>
+
* fhandler_disk_file.cc (fhandler_disk_file::link): Only add .exe if
original file has .exe as well.
* path.cc (path_conv::is_binary): Only recognize Windows 32 and 64 bit
diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h
index d38bdaf..da29726 100644
--- a/winsup/cygwin/ntdll.h
+++ b/winsup/cygwin/ntdll.h
@@ -8,6 +8,7 @@
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
+#define STATUS_NOT_ALL_ASSIGNED ((NTSTATUS) 0x00000106)
#define STATUS_OBJECT_NAME_EXISTS ((NTSTATUS) 0x40000000)
#define STATUS_BUFFER_OVERFLOW ((NTSTATUS) 0x80000005)
#define STATUS_NO_MORE_FILES ((NTSTATUS) 0x80000006)
@@ -28,7 +29,7 @@
#define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS) 0xc0000034)
#define STATUS_OBJECT_PATH_NOT_FOUND ((NTSTATUS) 0xc000003A)
#define STATUS_SHARING_VIOLATION ((NTSTATUS) 0xc0000043)
-#define STATUS_EAS_NOT_SUPPORTED ((NTSTATUS) 0xC000004f)
+#define STATUS_EAS_NOT_SUPPORTED ((NTSTATUS) 0xc000004f)
#define STATUS_EA_TOO_LARGE ((NTSTATUS) 0xc0000050)
#define STATUS_NONEXISTENT_EA_ENTRY ((NTSTATUS) 0xc0000051)
#define STATUS_NO_EAS_ON_FILE ((NTSTATUS) 0xc0000052)
@@ -37,7 +38,7 @@
#define STATUS_WORKING_SET_QUOTA ((NTSTATUS) 0xc00000a1)
#define STATUS_NOT_SUPPORTED ((NTSTATUS) 0xc00000bb)
#define STATUS_DIRECTORY_NOT_EMPTY ((NTSTATUS) 0xc0000101)
-#define STATUS_NOT_ALL_ASSIGNED ((NTSTATUS) 0x00000106)
+#define STATUS_CANNOT_DELETE ((NTSTATUS) 0xc0000121)
#define STATUS_INVALID_LEVEL ((NTSTATUS) 0xc0000148)
#define STATUS_DLL_NOT_FOUND ((NTSTATUS) 0xc0000135)
#define STATUS_ENTRYPOINT_NOT_FOUND ((NTSTATUS) 0xc0000139)
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 858413c..0548ebb 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -405,14 +405,14 @@ unlink_nt (path_conv &pc)
flags |= FILE_OPEN_REPARSE_POINT;
pc.get_object_attr (attr, sec_none_nih);
- /* First try to open the file with sharing not allowed. If the file
- has an open handle on it, 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 by simply closing the handle
- the file will disappear. */
+ /* 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. */
bool move_to_bin = false;
- status = NtOpenFile (&fh, access, &attr, &io, 0, flags);
+ status = NtOpenFile (&fh, access, &attr, &io, FILE_SHARE_DELETE, flags);
if (status == STATUS_SHARING_VIOLATION)
{
move_to_bin = true;
@@ -470,16 +470,46 @@ unlink_nt (path_conv &pc)
FileDispositionInformation);
if (!NT_SUCCESS (status))
{
- syscall_printf ("Setting delete disposition failed, status = %p", status);
- /* Restore R/O attributes. */
- if (access & FILE_WRITE_ATTRIBUTES)
- NtSetAttributesFile (fh, pc.file_attributes ());
+ syscall_printf ("Setting delete disposition failed, status = %p",
+ status);
+ /* Trying to delete a hardlink to a file in use by the system in some
+ way (for instance, font files) by setting the delete disposition fails
+ with STATUS_CANNOT_DELETE. Strange enough, deleting these hardlinks
+ using delete-on-close semantic works.
+
+ Don't use delete-on-close on remote shares. If two processes
+ have open handles on a file and one of them calls unlink, the
+ file is removed from the remote share even though the other
+ process still has an open handle. That process than gets Win32
+ error 59, ERROR_UNEXP_NET_ERR when trying to access the file.
+ Microsoft KB 837665 describes this problem as a bug in 2K3, but
+ I have reproduced it on other systems. */
+ if (status == STATUS_CANNOT_DELETE && !pc.isremote ())
+ {
+ HANDLE fh2;
+ UNICODE_STRING fname;
+
+ /* Re-open from handle so we open the correct file no matter if it
+ has been moved to the bin or not. */
+ RtlInitUnicodeString (&fname, L"");
+ InitializeObjectAttributes (&attr, &fname, 0, fh, NULL);
+ status = NtOpenFile (&fh2, DELETE, &attr, &io,
+ move_to_bin ? FILE_SHARE_VALID_FLAGS
+ : FILE_SHARE_DELETE,
+ flags | FILE_DELETE_ON_CLOSE);
+ if (!NT_SUCCESS (status))
+ syscall_printf ("Setting delete-on-close failed, status = %p",
+ status);
+ else
+ NtClose (fh2);
+ }
}
- else if ((access & FILE_WRITE_ATTRIBUTES) && !pc.isdir ())
+ if ((access & FILE_WRITE_ATTRIBUTES)
+ && (!NT_SUCCESS (status) || !pc.isdir ()))
{
/* Restore R/O attribute to accommodate hardlinks. Don't try this
with directories! For some reason the below NtSetInformationFile
- changes the disposition for delete back to FALSE, at least on XP. */
+ changes the delete disposition back to FALSE, at least on XP. */
NtSetAttributesFile (fh, pc.file_attributes ());
}