Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2009-12-17 21:33:05 +0300
committerCorinna Vinschen <corinna@vinschen.de>2009-12-17 21:33:05 +0300
commit314c2d2fedc5f377c50defafc1e296240f8dbd38 (patch)
treecb01f7f0394276726f7a4c503d71944db926eb30
parent375dbb9d4cd3ee046f76a6c80d47b6614d05e49b (diff)
* syscalls.cc (try_to_bin): Handle remote shares as well. Just rename
files in this case, instead of moving them to the recycler. Create even more unique filename. Add comment to explain filename. (unlink_nt): Remove code returning with EBUSY on remote shares. Set bin_stat to move_to_bin except on NFS. Add comment to explain.
-rw-r--r--winsup/cygwin/ChangeLog8
-rw-r--r--winsup/cygwin/syscalls.cc149
2 files changed, 85 insertions, 72 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 584724115..043fda876 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,11 @@
+2009-12-17 Corinna Vinschen <corinna@vinschen.de>
+
+ * syscalls.cc (try_to_bin): Handle remote shares as well. Just rename
+ files in this case, instead of moving them to the recycler. Create
+ even more unique filename. Add comment to explain filename.
+ (unlink_nt): Remove code returning with EBUSY on remote shares.
+ Set bin_stat to move_to_bin except on NFS. Add comment to explain.
+
2009-12-17 Eric Blake <ebb9@byu.net>
* signal.cc (nanosleep): Support 'infinite' sleep times.
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 17b33c5ce..e563fbb08 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -185,61 +185,75 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access)
goto out;
/* Initialize recycler path. */
RtlInitEmptyUnicodeString (&recycler, recyclerbuf, sizeof recyclerbuf);
- if (wincap.has_recycle_dot_bin ()) /* NTFS and FAT since Vista */
- RtlAppendUnicodeToString (&recycler, L"\\$Recycle.Bin\\");
- else if (pc.fs_is_ntfs ()) /* NTFS up to 2K3 */
- RtlAppendUnicodeToString (&recycler, L"\\RECYCLER\\");
- else if (pc.fs_is_fat ()) /* FAT up to 2K3 */
- RtlAppendUnicodeToString (&recycler, L"\\Recycled\\");
- else
- goto out;
- /* Is the file a subdir of the recycler? */
- RtlInitCountedUnicodeString(&fname, pfni->FileName, pfni->FileNameLength);
- if (RtlEqualUnicodePathPrefix (&fname, &recycler, TRUE))
- goto out;
- /* Is fname the recycler? Temporarily hide trailing backslash. */
- recycler.Length -= sizeof (WCHAR);
- if (RtlEqualUnicodeString (&fname, &recycler, TRUE))
- goto out;
-
- /* Create root dir path from file name information. */
- RtlSplitUnicodePath (&fname, &fname, NULL);
- RtlSplitUnicodePath (pc.get_nt_native_path (), &root, NULL);
- root.Length -= fname.Length - sizeof (WCHAR);
-
- /* Open root directory. All recycler bin ops are caseinsensitive. */
- InitializeObjectAttributes (&attr, &root, OBJ_CASE_INSENSITIVE, NULL, NULL);
- status = NtOpenFile (&rootdir, FILE_TRAVERSE, &attr, &io,
- FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
- if (!NT_SUCCESS (status))
- {
- debug_printf ("NtOpenFile (%S) failed, %08x", &root, status);
- goto out;
- }
+ if (!pc.isremote ())
+ {
+ if (wincap.has_recycle_dot_bin ()) /* NTFS and FAT since Vista */
+ RtlAppendUnicodeToString (&recycler, L"\\$Recycle.Bin\\");
+ else if (pc.fs_is_ntfs ()) /* NTFS up to 2K3 */
+ RtlAppendUnicodeToString (&recycler, L"\\RECYCLER\\");
+ else if (pc.fs_is_fat ()) /* FAT up to 2K3 */
+ RtlAppendUnicodeToString (&recycler, L"\\Recycled\\");
+ else
+ goto out;
+ /* Is the file a subdir of the recycler? */
+ RtlInitCountedUnicodeString(&fname, pfni->FileName, pfni->FileNameLength);
+ if (RtlEqualUnicodePathPrefix (&fname, &recycler, TRUE))
+ goto out;
+ /* Is fname the recycler? Temporarily hide trailing backslash. */
+ recycler.Length -= sizeof (WCHAR);
+ if (RtlEqualUnicodeString (&fname, &recycler, TRUE))
+ goto out;
+
+ /* Create root dir path from file name information. */
+ RtlSplitUnicodePath (&fname, &fname, NULL);
+ RtlSplitUnicodePath (pc.get_nt_native_path (), &root, NULL);
+ root.Length -= fname.Length - sizeof (WCHAR);
+
+ /* Open root directory. All recycler bin ops are caseinsensitive. */
+ InitializeObjectAttributes (&attr, &root, OBJ_CASE_INSENSITIVE,
+ NULL, NULL);
+ status = NtOpenFile (&rootdir, FILE_TRAVERSE, &attr, &io,
+ FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
+ if (!NT_SUCCESS (status))
+ {
+ debug_printf ("NtOpenFile (%S) failed, %08x", &root, status);
+ goto out;
+ }
- /* Strip leading backslash */
- ++recycler.Buffer;
- recycler.Length -= sizeof (WCHAR);
- /* Store length of recycler base dir, should it be necessary to create it. */
- recycler_base_len = recycler.Length;
- /* On NTFS the recycler dir contains user specific subdirs, which are the
- actual recycle bins per user. The name if this dir is the string
- representation of the user SID. */
- if (pc.fs_is_ntfs ())
- {
- UNICODE_STRING sid;
- WCHAR sidbuf[128];
- /* Unhide trailing backslash. */
- recycler.Length += sizeof (WCHAR);
- RtlInitEmptyUnicodeString (&sid, sidbuf, sizeof sidbuf);
- /* In contrast to what MSDN claims, this function is already available
- since NT4. */
- RtlConvertSidToUnicodeString (&sid, cygheap->user.sid (), FALSE);
- RtlAppendUnicodeStringToString (&recycler, &sid);
- recycler_user_len = recycler.Length;
- }
- /* Create hopefully unique filename. */
- RtlAppendUnicodeToString (&recycler, L"\\cyg");
+ /* Strip leading backslash */
+ ++recycler.Buffer;
+ recycler.Length -= sizeof (WCHAR);
+ /* Store length of recycler base dir, if it's necessary to create it. */
+ recycler_base_len = recycler.Length;
+ /* On NTFS the recycler dir contains user specific subdirs, which are the
+ actual recycle bins per user. The name if this dir is the string
+ representation of the user SID. */
+ if (pc.fs_is_ntfs ())
+ {
+ UNICODE_STRING sid;
+ WCHAR sidbuf[128];
+ /* Unhide trailing backslash. */
+ recycler.Length += sizeof (WCHAR);
+ RtlInitEmptyUnicodeString (&sid, sidbuf, sizeof sidbuf);
+ /* In contrast to what MSDN claims, this function is already available
+ since NT4. */
+ RtlConvertSidToUnicodeString (&sid, cygheap->user.sid (), FALSE);
+ RtlAppendUnicodeStringToString (&recycler, &sid);
+ recycler_user_len = recycler.Length;
+ }
+ RtlAppendUnicodeToString (&recycler, L"\\");
+ }
+ /* Create hopefully unique filename.
+ Since we have to stick to the current directory on remote shares, make
+ the new filename at least very unlikely to match by accident. It starts
+ with ".cyg", with "cyg" transposed into the Unicode low surrogate area
+ starting at U+dc00. Use plain ASCII chars on filesystems not supporting
+ Unicode. The rest of the filename is the inode number in hex encoding
+ and a hash of the full NT path in hex. The combination allows to remove
+ multiple hardlinks to the same file. */
+ RtlAppendUnicodeToString (&recycler,
+ pc.fs_flags () & FILE_UNICODE_ON_DISK
+ ? L".\xdc63\xdc79\xdc67" : L".cyg");
pfii = (PFILE_INTERNAL_INFORMATION) infobuf;
status = NtQueryInformationFile (fh, &io, pfii, 65536,
FileInternalInformation);
@@ -250,14 +264,16 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access)
goto out;
}
RtlInt64ToHexUnicodeString (pfii->FileId.QuadPart, &recycler, TRUE);
+ RtlInt64ToHexUnicodeString (hash_path_name (0, pc.get_nt_native_path ()),
+ &recycler, TRUE);
/* Shoot. */
pfri = (PFILE_RENAME_INFORMATION) infobuf;
pfri->ReplaceIfExists = TRUE;
- pfri->RootDirectory = rootdir;
+ pfri->RootDirectory = pc.isremote () ? NULL : rootdir;
pfri->FileNameLength = recycler.Length;
memcpy (pfri->FileName, recycler.Buffer, recycler.Length);
status = NtSetInformationFile (fh, &io, pfri, 65536, FileRenameInformation);
- if (status == STATUS_OBJECT_PATH_NOT_FOUND)
+ if (status == STATUS_OBJECT_PATH_NOT_FOUND && !pc.isremote ())
{
/* Ok, so the recycler and/or the recycler/SID directory don't exist.
First reopen root dir with permission to create subdirs. */
@@ -503,23 +519,12 @@ unlink_nt (path_conv &pc)
generated all the time. It looks like wrong file state information
is stored within the NFS client, for no apparent reason, which never
times out. Opening the file with FILE_SHARE_VALID_FLAGS will work,
- though, and it is then possible to delete the file quite normally. */
+ though, and it is then possible to delete the file quite normally.
- /* The recycle bin is only accessible locally. For in-use remote
- files we drop back to just returning EBUSY, except for NFS. */
- if (pc.isremote () && status == STATUS_SHARING_VIOLATION
- && !pc.fs_is_nfs ())
- {
- if (fh_ro)
- {
- /* Try to reset R/O attribute and close handle. */
- NtSetAttributesFile (fh_ro, pc.file_attributes ());
- NtClose (fh_ro);
- }
- return status;
- }
- /* Only local FS and NFS should arrive here. */
- if (!pc.isremote ())
+ NFS implements its own mechanism to remove in-use files which
+ looks quite similar to what we do in try_to_bin for remote files.
+ That's why we don't call try_to_bin on NFS. */
+ if (!pc.fs_is_nfs ())
bin_stat = move_to_bin;
if (!pc.isdir () || pc.isremote ())
status = NtOpenFile (&fh, access, &attr, &io,