* syscalls.cc (rename): Check if oldpath and newpath refer to the
same file. If so, return successfully and perform no other action, as per SUSv3.
This commit is contained in:
parent
13c9f5c677
commit
ae08b378c9
@ -1,3 +1,9 @@
|
|||||||
|
2007-08-01 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* syscalls.cc (rename): Check if oldpath and newpath refer to the
|
||||||
|
same file. If so, return successfully and perform no other action,
|
||||||
|
as per SUSv3.
|
||||||
|
|
||||||
2007-08-01 Corinna Vinschen <corinna@vinschen.de>
|
2007-08-01 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* ntdll.h (STATUS_ACCESS_DENIED): Define.
|
* ntdll.h (STATUS_ACCESS_DENIED): Define.
|
||||||
|
@ -1353,7 +1353,7 @@ rename (const char *oldpath, const char *newpath)
|
|||||||
bool old_explicit_suffix = false, new_explicit_suffix = false;
|
bool old_explicit_suffix = false, new_explicit_suffix = false;
|
||||||
size_t olen, nlen;
|
size_t olen, nlen;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
HANDLE fh;
|
HANDLE fh, nfh;
|
||||||
OBJECT_ATTRIBUTES attr;
|
OBJECT_ATTRIBUTES attr;
|
||||||
IO_STATUS_BLOCK io;
|
IO_STATUS_BLOCK io;
|
||||||
ULONG size;
|
ULONG size;
|
||||||
@ -1520,6 +1520,40 @@ rename (const char *oldpath, const char *newpath)
|
|||||||
__seterrno_from_nt_status (status);
|
__seterrno_from_nt_status (status);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
if ((removepc || dstpc->exists ())
|
||||||
|
&& NT_SUCCESS (NtOpenFile (&nfh, READ_CONTROL,
|
||||||
|
(removepc ?: dstpc)->get_object_attr (attr, sec_none_nih),
|
||||||
|
&io, FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT)))
|
||||||
|
{
|
||||||
|
size_t size = sizeof (FILE_FS_VOLUME_INFORMATION) + 32 * sizeof (WCHAR);
|
||||||
|
PFILE_FS_VOLUME_INFORMATION opffvi = (PFILE_FS_VOLUME_INFORMATION)
|
||||||
|
alloca (size);
|
||||||
|
PFILE_FS_VOLUME_INFORMATION npffvi = (PFILE_FS_VOLUME_INFORMATION)
|
||||||
|
alloca (size);
|
||||||
|
FILE_INTERNAL_INFORMATION ofii, nfii;
|
||||||
|
|
||||||
|
/* SUSv3: If the old argument and the new argument resolve to the same
|
||||||
|
existing file, rename() shall return successfully and perform no
|
||||||
|
other action. */
|
||||||
|
if (NT_SUCCESS (NtQueryVolumeInformationFile (fh, &io, opffvi, size,
|
||||||
|
FileFsVolumeInformation))
|
||||||
|
&& NT_SUCCESS (NtQueryVolumeInformationFile (nfh, &io, npffvi, size,
|
||||||
|
FileFsVolumeInformation))
|
||||||
|
&& opffvi->VolumeSerialNumber == npffvi->VolumeSerialNumber
|
||||||
|
&& NT_SUCCESS (NtQueryInformationFile (fh, &io, &ofii, sizeof ofii,
|
||||||
|
FileInternalInformation))
|
||||||
|
&& NT_SUCCESS (NtQueryInformationFile (nfh, &io, &nfii, sizeof nfii,
|
||||||
|
FileInternalInformation))
|
||||||
|
&& ofii.FileId.QuadPart == nfii.FileId.QuadPart)
|
||||||
|
{
|
||||||
|
debug_printf ("%s and %s are the same file", oldpath, newpath);
|
||||||
|
NtClose (nfh);
|
||||||
|
NtClose (fh);
|
||||||
|
res = 0;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
NtClose (nfh);
|
||||||
|
}
|
||||||
size = sizeof (FILE_RENAME_INFORMATION)
|
size = sizeof (FILE_RENAME_INFORMATION)
|
||||||
+ dstpc->get_nt_native_path ()->Length;
|
+ dstpc->get_nt_native_path ()->Length;
|
||||||
pfri = (PFILE_RENAME_INFORMATION) alloca (size);
|
pfri = (PFILE_RENAME_INFORMATION) alloca (size);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user