diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2017-07-01 14:38:55 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2017-07-20 01:17:28 +0000 |
commit | cb9b42b493d168544ec8e4d6ff10c74cbdc70942 (patch) | |
tree | f6f1194d63ab188a7703bae522b0fbc185119cc7 /src/corelib | |
parent | a639a4cc075bea7f55171ebca786cb46e72e34f3 (diff) |
QFileSystemEngine: a file only exists if its link count is not 0
QFileSystemMetaData::fillFromStatBuf is used when filling in the results
from both stat() as well as fstat(). Obviously the file exists if it was
stat()ed but not necessarily so by fstat(): we could be operating on a
file descriptor referring to an unlinked file or an O_TMPFILE.
Change-Id: I8d96dea9955d4c749b99fffd14cd52a8c8dd9ca1
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/io/qfile.cpp | 2 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemengine.cpp | 4 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemmetadata_p.h | 11 | ||||
-rw-r--r-- | src/corelib/io/qfsfileengine_unix.cpp | 8 | ||||
-rw-r--r-- | src/corelib/io/qfsfileengine_win.cpp | 2 |
5 files changed, 21 insertions, 6 deletions
diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index c7a06e49d5..af7ff74389 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -421,7 +421,7 @@ QFile::exists() const Q_D(const QFile); // 0x1000000 = QAbstractFileEngine::Refresh, forcing an update return (d->engine()->fileFlags(QAbstractFileEngine::FlagsMask - | QAbstractFileEngine::FileFlag(0x1000000)) & QAbstractFileEngine::ExistsFlag); + | QAbstractFileEngine::Refresh) & QAbstractFileEngine::ExistsFlag); } /*! diff --git a/src/corelib/io/qfilesystemengine.cpp b/src/corelib/io/qfilesystemengine.cpp index ccbcdb1037..f3205ae6e2 100644 --- a/src/corelib/io/qfilesystemengine.cpp +++ b/src/corelib/io/qfilesystemengine.cpp @@ -281,7 +281,9 @@ void QFileSystemMetaData::fillFromStatBuf(const QT_STATBUF &statBuffer) entryFlags |= QFileSystemMetaData::SequentialType; // Attributes - entryFlags |= QFileSystemMetaData::ExistsAttribute; + entryFlags |= QFileSystemMetaData::ExistsAttribute; // inode exists + if (statBuffer.st_nlink == 0) + entryFlags |= QFileSystemMetaData::WasDeletedAttribute; size_ = statBuffer.st_size; #if defined(Q_OS_DARWIN) if (statBuffer.st_flags & UF_HIDDEN) { diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h index b09223d656..2f25721bee 100644 --- a/src/corelib/io/qfilesystemmetadata_p.h +++ b/src/corelib/io/qfilesystemmetadata_p.h @@ -120,9 +120,14 @@ public: // Attributes HiddenAttribute = 0x00100000, SizeAttribute = 0x00200000, // Note: overlaps with QAbstractFileEngine::LocalDiskFlag - ExistsAttribute = 0x00400000, + ExistsAttribute = 0x00400000, // For historical reasons, indicates existence of data, not the file +#if defined(Q_OS_WIN) + WasDeletedAttribute = 0x0, +#else + WasDeletedAttribute = 0x40000000, // Indicates the file was deleted +#endif - Attributes = HiddenAttribute | SizeAttribute | ExistsAttribute, + Attributes = HiddenAttribute | SizeAttribute | ExistsAttribute | WasDeletedAttribute, // Times CreationTime = 0x01000000, // Note: overlaps with QAbstractFileEngine::Refresh @@ -144,6 +149,7 @@ public: | QFileSystemMetaData::DirectoryType | QFileSystemMetaData::SequentialType | QFileSystemMetaData::SizeAttribute + | QFileSystemMetaData::WasDeletedAttribute | QFileSystemMetaData::Times | QFileSystemMetaData::OwnerIds, @@ -191,6 +197,7 @@ public: bool isLegacyLink() const { return (entryFlags & LegacyLinkType); } bool isSequential() const { return (entryFlags & SequentialType); } bool isHidden() const { return (entryFlags & HiddenAttribute); } + bool wasDeleted() const { return (entryFlags & WasDeletedAttribute); } #if defined(Q_OS_WIN) bool isLnkFile() const { return (entryFlags & WinLnkType); } #else diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 69961ff76a..dadd5d9bcf 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -495,11 +495,14 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(FileFlags type) const | QFileSystemMetaData::LinkType | QFileSystemMetaData::FileType | QFileSystemMetaData::DirectoryType - | QFileSystemMetaData::BundleType; + | QFileSystemMetaData::BundleType + | QFileSystemMetaData::WasDeletedAttribute; if (type & FlagsMask) queryFlags |= QFileSystemMetaData::HiddenAttribute | QFileSystemMetaData::ExistsAttribute; + else if (type & ExistsFlag) + queryFlags |= QFileSystemMetaData::WasDeletedAttribute; queryFlags |= QFileSystemMetaData::LinkType; @@ -531,7 +534,8 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(FileFlags type) const } if (type & FlagsMask) { - if (exists) + // the inode existing does not mean the file exists + if (!d->metaData.wasDeleted()) ret |= ExistsFlag; if (d->fileEntry.isRoot()) ret |= RootFlag; diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index d749e32447..6d8db1a72e 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -741,6 +741,8 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::Fil } if (type & FlagsMask) { if (d->metaData.exists()) { + // if we succeeded in querying, then the file exists: a file on + // Windows cannot be deleted if we have an open handle to it ret |= ExistsFlag; if (d->fileEntry.isRoot()) ret |= RootFlag; |