QFile::rename: avoid two stat(2)/CreateFile in a row
QFileSystemEngine::id() will stat(2)/CreateFile in order to get the ID of the file anyway, so we don't need to use QFile::exists() to check if the destination exists. Instead, rely on id() returning a null value to indicate error. On Windows, it's possible that the calls to either GetFileInformationByHandle or GetFileInformationByHandleEx might fail, but we ignore those. Change-Id: I1eba2b016de74620bfc8fffd14ccaebcbed64419 Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@qt.io>
This commit is contained in:
parent
353fb118c3
commit
fd95ef765a
@ -567,9 +567,11 @@ QFile::rename(const QString &newName)
|
||||
}
|
||||
// If the file exists and it is a case-changing rename ("foo" -> "Foo"),
|
||||
// compare Ids to make sure it really is a different file.
|
||||
if (QFile::exists(newName)) {
|
||||
if (d->fileName.compare(newName, Qt::CaseInsensitive)
|
||||
|| QFileSystemEngine::id(QFileSystemEntry(d->fileName)) != QFileSystemEngine::id(QFileSystemEntry(newName))) {
|
||||
// Note: this does not take file engines into account.
|
||||
QByteArray targetId = QFileSystemEngine::id(QFileSystemEntry(newName));
|
||||
if (!targetId.isNull()) {
|
||||
QByteArray fileId = QFileSystemEngine::id(QFileSystemEntry(d->fileName));
|
||||
if (fileId != targetId || d->fileName.compare(newName, Qt::CaseInsensitive)) {
|
||||
// ### Race condition. If a file is moved in after this, it /will/ be
|
||||
// overwritten. On Unix, the proper solution is to use hardlinks:
|
||||
// return ::link(old, new) && ::remove(old);
|
||||
|
@ -338,7 +338,8 @@ QByteArray QFileSystemEngine::id(const QFileSystemEntry &entry)
|
||||
{
|
||||
QT_STATBUF statResult;
|
||||
if (QT_STAT(entry.nativeFilePath().constData(), &statResult)) {
|
||||
qErrnoWarning("stat() failed for '%s'", entry.nativeFilePath().constData());
|
||||
if (errno != ENOENT)
|
||||
qErrnoWarning("stat() failed for '%s'", entry.nativeFilePath().constData());
|
||||
return QByteArray();
|
||||
}
|
||||
QByteArray result = QByteArray::number(quint64(statResult.st_dev), 16);
|
||||
|
Loading…
Reference in New Issue
Block a user