Cygwin: rename: use FILE_RENAME_POSIX_SEMANTICS if available
starting with W10 1709 on local NTFS drives Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
15094d5d01
commit
ec457e0351
|
@ -37,6 +37,10 @@ What changed:
|
||||||
Deleting an in-use file now actually removes the file, rather than moving
|
Deleting an in-use file now actually removes the file, rather than moving
|
||||||
it to the recycler bin.
|
it to the recycler bin.
|
||||||
|
|
||||||
|
- Use the new POSIX rename semantics on NTFS starting with Windows 10 1709.
|
||||||
|
Renaming a file to another in-use file now actually removes the other file,
|
||||||
|
rather than moving it to the recycler bin.
|
||||||
|
|
||||||
- open(..., O_TMPFILE) now moves the file to the trash bin immediately,
|
- open(..., O_TMPFILE) now moves the file to the trash bin immediately,
|
||||||
to free the parent directory.
|
to free the parent directory.
|
||||||
|
|
||||||
|
|
|
@ -2216,6 +2216,7 @@ rename2 (const char *oldpath, const char *newpath, unsigned int at2flags)
|
||||||
path_conv oldpc, newpc, new2pc, *dstpc, *removepc = NULL;
|
path_conv oldpc, newpc, new2pc, *dstpc, *removepc = NULL;
|
||||||
bool old_dir_requested = false, new_dir_requested = false;
|
bool old_dir_requested = false, new_dir_requested = false;
|
||||||
bool old_explicit_suffix = false, new_explicit_suffix = false;
|
bool old_explicit_suffix = false, new_explicit_suffix = false;
|
||||||
|
bool use_posix_semantics;
|
||||||
bool noreplace = at2flags & RENAME_NOREPLACE;
|
bool noreplace = at2flags & RENAME_NOREPLACE;
|
||||||
size_t olen, nlen;
|
size_t olen, nlen;
|
||||||
bool equal_path;
|
bool equal_path;
|
||||||
|
@ -2511,10 +2512,18 @@ rename2 (const char *oldpath, const char *newpath, unsigned int at2flags)
|
||||||
__leave;
|
__leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* POSIX semantics only on local NTFS drives. */
|
||||||
|
use_posix_semantics = wincap.has_posix_file_info ()
|
||||||
|
&& !oldpc.isremote ()
|
||||||
|
&& oldpc.fs_is_ntfs ();
|
||||||
|
|
||||||
/* Opening the file must be part of the transaction. It's not sufficient
|
/* Opening the file must be part of the transaction. It's not sufficient
|
||||||
to call only NtSetInformationFile under the transaction. Therefore we
|
to call only NtSetInformationFile under the transaction. Therefore we
|
||||||
have to start the transaction here, if necessary. */
|
have to start the transaction here, if necessary. Don't start
|
||||||
if ((dstpc->fs_flags () & FILE_SUPPORTS_TRANSACTIONS)
|
transaction on W10 1709 or later on local NTFS. Use POSIX semantics
|
||||||
|
instead. */
|
||||||
|
if (!use_posix_semantics
|
||||||
|
&& (dstpc->fs_flags () & FILE_SUPPORTS_TRANSACTIONS)
|
||||||
&& (dstpc->isdir ()
|
&& (dstpc->isdir ()
|
||||||
|| (!removepc && dstpc->has_attribute (FILE_ATTRIBUTE_READONLY))))
|
|| (!removepc && dstpc->has_attribute (FILE_ATTRIBUTE_READONLY))))
|
||||||
start_transaction (old_trans, trans);
|
start_transaction (old_trans, trans);
|
||||||
|
@ -2578,6 +2587,9 @@ rename2 (const char *oldpath, const char *newpath, unsigned int at2flags)
|
||||||
__leave;
|
__leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (use_posix_semantics)
|
||||||
|
goto skip_pre_W10_checks;
|
||||||
|
|
||||||
/* Renaming a dir to another, existing dir fails always, even if
|
/* Renaming a dir to another, existing dir fails always, even if
|
||||||
ReplaceIfExists is set to TRUE and the existing dir is empty. So
|
ReplaceIfExists is set to TRUE and the existing dir is empty. So
|
||||||
we have to remove the destination dir first. This also covers the
|
we have to remove the destination dir first. This also covers the
|
||||||
|
@ -2619,6 +2631,8 @@ rename2 (const char *oldpath, const char *newpath, unsigned int at2flags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
skip_pre_W10_checks:
|
||||||
|
|
||||||
/* SUSv3: If the old argument and the new argument resolve to the same
|
/* SUSv3: If the old argument and the new argument resolve to the same
|
||||||
existing file, rename() shall return successfully and perform no
|
existing file, rename() shall return successfully and perform no
|
||||||
other action.
|
other action.
|
||||||
|
@ -2666,6 +2680,12 @@ rename2 (const char *oldpath, const char *newpath, unsigned int at2flags)
|
||||||
__leave;
|
__leave;
|
||||||
}
|
}
|
||||||
pfri = (PFILE_RENAME_INFORMATION) tp.w_get ();
|
pfri = (PFILE_RENAME_INFORMATION) tp.w_get ();
|
||||||
|
if (use_posix_semantics)
|
||||||
|
pfri->Flags = noreplace ? 0
|
||||||
|
: (FILE_RENAME_REPLACE_IF_EXISTS
|
||||||
|
| FILE_RENAME_POSIX_SEMANTICS
|
||||||
|
| FILE_RENAME_IGNORE_READONLY_ATTRIBUTE);
|
||||||
|
else
|
||||||
pfri->ReplaceIfExists = !noreplace;
|
pfri->ReplaceIfExists = !noreplace;
|
||||||
pfri->RootDirectory = NULL;
|
pfri->RootDirectory = NULL;
|
||||||
pfri->FileNameLength = dstpc->get_nt_native_path ()->Length;
|
pfri->FileNameLength = dstpc->get_nt_native_path ()->Length;
|
||||||
|
@ -2677,7 +2697,9 @@ rename2 (const char *oldpath, const char *newpath, unsigned int at2flags)
|
||||||
ERROR_ALREADY_EXISTS ==> Cygwin error EEXIST. */
|
ERROR_ALREADY_EXISTS ==> Cygwin error EEXIST. */
|
||||||
status = NtSetInformationFile (fh, &io, pfri,
|
status = NtSetInformationFile (fh, &io, pfri,
|
||||||
sizeof *pfri + pfri->FileNameLength,
|
sizeof *pfri + pfri->FileNameLength,
|
||||||
FileRenameInformation);
|
use_posix_semantics
|
||||||
|
? FileRenameInformationEx
|
||||||
|
: FileRenameInformation);
|
||||||
/* This happens if the access rights don't allow deleting the destination.
|
/* This happens if the access rights don't allow deleting the destination.
|
||||||
Even if the handle to the original file is opened with BACKUP
|
Even if the handle to the original file is opened with BACKUP
|
||||||
and/or RECOVERY, these flags don't apply to the destination of the
|
and/or RECOVERY, these flags don't apply to the destination of the
|
||||||
|
|
|
@ -54,6 +54,12 @@ all clocks, except CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID.
|
||||||
clock_setres is a no-op now.
|
clock_setres is a no-op now.
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
|
|
||||||
|
<listitem><para>
|
||||||
|
Use the new POSIX rename semantics on NTFS starting with Windows 10
|
||||||
|
1709. Renaming a file to another in-use file now actually removes the
|
||||||
|
other file, rather than moving it to the recycler bin.
|
||||||
|
</para></listitem>
|
||||||
|
|
||||||
<listitem><para>
|
<listitem><para>
|
||||||
Use the new POSIX unlink semantics on NTFS starting with Windows 10
|
Use the new POSIX unlink semantics on NTFS starting with Windows 10
|
||||||
1709. Deleting an in-use file now actually removes the file, rather
|
1709. Deleting an in-use file now actually removes the file, rather
|
||||||
|
|
Loading…
Reference in New Issue