Cygwin: try_to_bin: allow to move O_TMPFILE files into bin

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2019-01-05 21:44:12 +01:00
parent 732613f30a
commit a1a750325e
1 changed files with 33 additions and 26 deletions

View File

@ -328,34 +328,38 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access, ULONG flags)
} }
RtlAppendUnicodeToString (&recycler, L"\\"); RtlAppendUnicodeToString (&recycler, L"\\");
} }
/* Create hopefully unique filename. if (pc.file_attributes () & FILE_ATTRIBUTE_TEMPORARY)
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 UNICODE_STRING basename;
with ".cyg", with "cyg" transposed into the Unicode low surrogate area
starting at U+dc00. Use plain ASCII chars on filesystems not supporting RtlSplitUnicodePath (pc.get_nt_native_path (), NULL, &basename);
Unicode. The rest of the filename is the inode number in hex encoding RtlAppendUnicodeToString (&recycler, basename.Buffer);
and a hash of the full NT path in hex. The combination allows to remove }
multiple hardlinks to the same file. Samba doesn't like the transposed else
names. */ {
/* Create unique filename. Start with a dot, followed by "cyg"
transposed into the Unicode low surrogate area (U+dc00) on file
systems supporting Unicode (except Samba), followed by the inode
number in hex, followed by a path hash in hex. The combination
allows to remove multiple hardlinks to the same file. */
RtlAppendUnicodeToString (&recycler, RtlAppendUnicodeToString (&recycler,
(pc.fs_flags () & FILE_UNICODE_ON_DISK (pc.fs_flags () & FILE_UNICODE_ON_DISK
&& !pc.fs_is_samba ()) && !pc.fs_is_samba ())
? L".\xdc63\xdc79\xdc67" : L".cyg"); ? L".\xdc63\xdc79\xdc67" : L".cyg");
pfii = (PFILE_INTERNAL_INFORMATION) infobuf; pfii = (PFILE_INTERNAL_INFORMATION) infobuf;
/* Note: Modern Samba versions apparently don't like buffer sizes of more
than 65535 in some NtQueryInformationFile/NtSetInformationFile calls.
Therefore we better use exact buffer sizes from now on. */
status = NtQueryInformationFile (fh, &io, pfii, sizeof *pfii, status = NtQueryInformationFile (fh, &io, pfii, sizeof *pfii,
FileInternalInformation); FileInternalInformation);
if (!NT_SUCCESS (status)) if (!NT_SUCCESS (status))
{ {
debug_printf ("NtQueryInformationFile (%S, FileInternalInformation) " debug_printf ("NtQueryInformationFile (%S, FileInternalInformation) "
"failed, status = %y", pc.get_nt_native_path (), status); "failed, status = %y",
pc.get_nt_native_path (), status);
goto out; goto out;
} }
RtlInt64ToHexUnicodeString (pfii->IndexNumber.QuadPart, &recycler, TRUE); RtlInt64ToHexUnicodeString (pfii->IndexNumber.QuadPart, &recycler, TRUE);
RtlInt64ToHexUnicodeString (hash_path_name (0, pc.get_nt_native_path ()), RtlInt64ToHexUnicodeString (hash_path_name (0, pc.get_nt_native_path ()),
&recycler, TRUE); &recycler, TRUE);
}
/* Shoot. */ /* Shoot. */
pfri = (PFILE_RENAME_INFORMATION) infobuf; pfri = (PFILE_RENAME_INFORMATION) infobuf;
pfri->ReplaceIfExists = TRUE; pfri->ReplaceIfExists = TRUE;
@ -461,6 +465,9 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access, ULONG flags)
} }
/* Moving to the bin worked. */ /* Moving to the bin worked. */
bin_stat = has_been_moved; bin_stat = has_been_moved;
/* If we're only moving a just created O_TMPFILE, we're done here. */
if (pc.file_attributes () & FILE_ATTRIBUTE_TEMPORARY)
goto out;
/* Now we try to set the delete disposition. If that worked, we're done. /* Now we try to set the delete disposition. If that worked, we're done.
We try this here first, as long as we still have the open handle. We try this here first, as long as we still have the open handle.
Otherwise the below code closes the handle to allow replacing the file. */ Otherwise the below code closes the handle to allow replacing the file. */