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>
+
* ntdll.h (STATUS_ACCESS_DENIED): Define.
* syscalls.cc (check_dir_not_empty): New static function.
(unlink_nt): Move code checking for non-empty dir to check_dir_not_empty
bool old_explicit_suffix = false, new_explicit_suffix = false;
size_t olen, nlen;
NTSTATUS status;
- HANDLE fh;
+ HANDLE fh, nfh;
OBJECT_ATTRIBUTES attr;
IO_STATUS_BLOCK io;
ULONG size;
__seterrno_from_nt_status (status);
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)
+ dstpc->get_nt_native_path ()->Length;
pfri = (PFILE_RENAME_INFORMATION) alloca (size);