summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2017-07-01 14:38:55 -0700
committerThiago Macieira <thiago.macieira@intel.com>2017-07-20 01:17:28 +0000
commitcb9b42b493d168544ec8e4d6ff10c74cbdc70942 (patch)
treef6f1194d63ab188a7703bae522b0fbc185119cc7 /src/corelib
parenta639a4cc075bea7f55171ebca786cb46e72e34f3 (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.cpp2
-rw-r--r--src/corelib/io/qfilesystemengine.cpp4
-rw-r--r--src/corelib/io/qfilesystemmetadata_p.h11
-rw-r--r--src/corelib/io/qfsfileengine_unix.cpp8
-rw-r--r--src/corelib/io/qfsfileengine_win.cpp2
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;