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>2013-11-27 18:27:34 +0400
committerCorinna Vinschen <corinna@vinschen.de>2013-11-27 18:27:34 +0400
commit854ed5f03a4d92990a512ef43665bb137d9f0f46 (patch)
treeab05e67602b6aaa37ae9d278a3d9fbf14b087578
parent963addfa27ac86f0b337ed8559d1b8fc3fb01eb7 (diff)
* syscalls.cc (try_to_bin): Take additional parameter to get file open
flags. If the file to move to the bin has been opened casesensitive, reopen it caseinsensitive. Explain why. Revert the default name of the Vista-and-later recycler to mixed case for readability. (unlink_nt): Call try_to_bin with file open flags as evaluated.
-rw-r--r--winsup/cygwin/ChangeLog8
-rw-r--r--winsup/cygwin/release/1.7.264
-rw-r--r--winsup/cygwin/syscalls.cc36
3 files changed, 43 insertions, 5 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 07334185d..f41deeb2f 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,11 @@
+2013-11-27 Corinna Vinschen <corinna@vinschen.de>
+
+ * syscalls.cc (try_to_bin): Take additional parameter to get file open
+ flags. If the file to move to the bin has been opened casesensitive,
+ reopen it caseinsensitive. Explain why. Revert the default name of
+ the Vista-and-later recycler to mixed case for readability.
+ (unlink_nt): Call try_to_bin with file open flags as evaluated.
+
2013-11-26 Corinna Vinschen <corinna@vinschen.de>
* nlsfuncs.cc (wcscoll): Add "__restrict" to definition.
diff --git a/winsup/cygwin/release/1.7.26 b/winsup/cygwin/release/1.7.26
index 12935d38c..ef838126c 100644
--- a/winsup/cygwin/release/1.7.26
+++ b/winsup/cygwin/release/1.7.26
@@ -65,3 +65,7 @@ Bug fixes:
- dup2() could crash in some cases for a destination >= 256
Fixes: http://cygwin.com/ml/cygwin/2013-09/msg00397.html
+
+- Try to workaround the following problem: unlink(2) could fail, if the
+ file was opened casesensitive and has to be moved to the recycler due
+ to a sharing violation.
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index ec79e57c1..243fd8642 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -232,7 +232,7 @@ enum bin_status
};
static bin_status
-try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access)
+try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access, ULONG flags)
{
bin_status bin_stat = move_to_bin;
NTSTATUS status;
@@ -268,12 +268,37 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access)
them into the recycler. */
if (pfni->FileNameLength == 2) /* root dir. */
goto out;
+ /* The recycler name on Vista and later is $Recycler.Bin by default. If the
+ recycler dir disappeared for some reason, the shell32.dll recreates the
+ directory in all upper case. So, we never know beforehand if the dir
+ is written in mixed case or in all upper case. That's a problem when
+ using casesensitivity. If the file handle given to FileRenameInformation
+ has been opened casesensitive, the call also handles the path to the
+ target dir casesensitive. Rather then trying to find the right name
+ of the recycler, we just reopen the file to move with OBJ_CASE_INSENSITIVE,
+ so the subsequent FileRenameInformation works caseinsensitive in terms of
+ the recycler directory name, too. */
+ if (!pc.objcaseinsensitive ())
+ {
+ HANDLE fh_dup;
+ InitializeObjectAttributes (&attr, &ro_u_empty, OBJ_CASE_INSENSITIVE,
+ fh, NULL);
+ status = NtOpenFile (&fh_dup, access, &attr, &io, FILE_SHARE_VALID_FLAGS,
+ flags);
+ if (!NT_SUCCESS (status))
+ debug_printf ("NtOpenFile (reopen) failed, status = %y", status);
+ else
+ {
+ NtClose (fh);
+ fh = fh_dup;
+ }
+ }
/* Initialize recycler path. */
RtlInitEmptyUnicodeString (&recycler, recyclerbuf, sizeof recyclerbuf);
if (!pc.isremote ())
{
if (wincap.has_recycle_dot_bin ()) /* NTFS and FAT since Vista, ReFS */
- RtlAppendUnicodeToString (&recycler, L"\\$RECYCLE.BIN\\");
+ 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 */
@@ -359,6 +384,7 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access)
pfri->FileNameLength = recycler.Length;
memcpy (pfri->FileName, recycler.Buffer, recycler.Length);
frisiz = sizeof *pfri + pfri->FileNameLength - sizeof (WCHAR);
+
status = NtSetInformationFile (fh, &io, pfri, frisiz, FileRenameInformation);
if (status == STATUS_OBJECT_PATH_NOT_FOUND && !pc.isremote ())
{
@@ -786,7 +812,7 @@ unlink_nt (path_conv &pc)
/* Try to move to bin if a sharing violation occured. If that worked,
we're done. */
if (bin_stat == move_to_bin
- && (bin_stat = try_to_bin (pc, fh, access)) >= has_been_moved)
+ && (bin_stat = try_to_bin (pc, fh, access, flags)) >= has_been_moved)
{
if (bin_stat == has_been_moved)
status = STATUS_SUCCESS;
@@ -856,7 +882,7 @@ try_again:
{
debug_printf ("Try-to-bin %S",
pc.get_nt_native_path ());
- bin_stat = try_to_bin (pc, fh, access);
+ bin_stat = try_to_bin (pc, fh, access, flags);
}
}
/* Do NOT handle bin_stat == dir_not_empty here! */
@@ -916,7 +942,7 @@ try_again:
succeeds, we got rid of the file in some way, even if
unlinking didn't work. */
if (bin_stat == dont_move)
- bin_stat = try_to_bin (pc, fh, access);
+ bin_stat = try_to_bin (pc, fh, access, flags);
if (bin_stat >= has_been_moved)
status = bin_stat == has_been_moved
? STATUS_SUCCESS