From 12339481ea016845ffb79e83d9b3dfb6849c7652 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 2 Jul 2017 11:20:54 -0700 Subject: [PATCH] Move Unix code from qfilesystemengine.cpp to qfilesystemengine_unix.cpp The comment about Symbian no longer applies. Change-Id: I8d96dea9955d4c749b99fffd14cd966f07d95948 Reviewed-by: Lars Knoll --- src/corelib/io/qfilesystemengine.cpp | 223 ---------------------- src/corelib/io/qfilesystemengine_unix.cpp | 218 +++++++++++++++++++++ 2 files changed, 218 insertions(+), 223 deletions(-) diff --git a/src/corelib/io/qfilesystemengine.cpp b/src/corelib/io/qfilesystemengine.cpp index 1af5c6f4ed..955b459bba 100644 --- a/src/corelib/io/qfilesystemengine.cpp +++ b/src/corelib/io/qfilesystemengine.cpp @@ -204,229 +204,6 @@ QAbstractFileEngine *QFileSystemEngine::resolveEntryAndCreateLegacyEngine( return engine; } -//these unix functions are in this file, because they are shared by symbian port -//for open C file handles. -#ifdef Q_OS_UNIX -//static -bool QFileSystemEngine::fillMetaData(int fd, QFileSystemMetaData &data) -{ - data.entryFlags &= ~QFileSystemMetaData::PosixStatFlags; - data.knownFlagsMask |= QFileSystemMetaData::PosixStatFlags; - - QT_STATBUF statBuffer; - if (QT_FSTAT(fd, &statBuffer) == 0) { - data.fillFromStatBuf(statBuffer); - return true; - } - - return false; -} - -#if defined(_DEXTRA_FIRST) -static void fillStat64fromStat32(struct stat64 *statBuf64, const struct stat &statBuf32) -{ - statBuf64->st_mode = statBuf32.st_mode; - statBuf64->st_size = statBuf32.st_size; -#if _POSIX_VERSION >= 200809L - statBuf64->st_ctim = statBuf32.st_ctim; - statBuf64->st_mtim = statBuf32.st_mtim; - statBuf64->st_atim = statBuf32.st_atim; -#else - statBuf64->st_ctime = statBuf32.st_ctime; - statBuf64->st_mtime = statBuf32.st_mtime; - statBuf64->st_atime = statBuf32.st_atime; -#endif - statBuf64->st_uid = statBuf32.st_uid; - statBuf64->st_gid = statBuf32.st_gid; -} -#endif - -#if _POSIX_VERSION >= 200809L -static qint64 timespecToMSecs(const timespec &spec) -{ - return (qint64(spec.tv_sec) * 1000) + (spec.tv_nsec / 1000000); -} -#endif - -void QFileSystemMetaData::fillFromStatBuf(const QT_STATBUF &statBuffer) -{ - // Permissions - if (statBuffer.st_mode & S_IRUSR) - entryFlags |= QFileSystemMetaData::OwnerReadPermission; - if (statBuffer.st_mode & S_IWUSR) - entryFlags |= QFileSystemMetaData::OwnerWritePermission; - if (statBuffer.st_mode & S_IXUSR) - entryFlags |= QFileSystemMetaData::OwnerExecutePermission; - - if (statBuffer.st_mode & S_IRGRP) - entryFlags |= QFileSystemMetaData::GroupReadPermission; - if (statBuffer.st_mode & S_IWGRP) - entryFlags |= QFileSystemMetaData::GroupWritePermission; - if (statBuffer.st_mode & S_IXGRP) - entryFlags |= QFileSystemMetaData::GroupExecutePermission; - - if (statBuffer.st_mode & S_IROTH) - entryFlags |= QFileSystemMetaData::OtherReadPermission; - if (statBuffer.st_mode & S_IWOTH) - entryFlags |= QFileSystemMetaData::OtherWritePermission; - if (statBuffer.st_mode & S_IXOTH) - entryFlags |= QFileSystemMetaData::OtherExecutePermission; - - // Type - if ((statBuffer.st_mode & S_IFMT) == S_IFREG) - entryFlags |= QFileSystemMetaData::FileType; - else if ((statBuffer.st_mode & S_IFMT) == S_IFDIR) - entryFlags |= QFileSystemMetaData::DirectoryType; - else if ((statBuffer.st_mode & S_IFMT) != S_IFBLK) - entryFlags |= QFileSystemMetaData::SequentialType; - - // Attributes - 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) { - entryFlags |= QFileSystemMetaData::HiddenAttribute; - knownFlagsMask |= QFileSystemMetaData::HiddenAttribute; - } -#endif - - // Times - birthTime_ = 0; -#if _POSIX_VERSION >= 200809L - modificationTime_ = timespecToMSecs(statBuffer.st_mtim); - metadataChangeTime_ = timespecToMSecs(statBuffer.st_ctim); - accessTime_ = timespecToMSecs(statBuffer.st_atim); -#else - modificationTime_ = qint64(statBuffer.st_mtime) * 1000; - metadataChangeTime_ = qint64(statBuffer.st_ctime) * 1000; - accessTime_ = qint64(statBuffer.st_atime) * 1000; -#endif - userId_ = statBuffer.st_uid; - groupId_ = statBuffer.st_gid; -} - -void QFileSystemMetaData::fillFromDirEnt(const QT_DIRENT &entry) -{ -#if defined(_DEXTRA_FIRST) - knownFlagsMask = 0; - entryFlags = 0; - for (dirent_extra *extra = _DEXTRA_FIRST(&entry); _DEXTRA_VALID(extra, &entry); - extra = _DEXTRA_NEXT(extra)) { - if (extra->d_type == _DTYPE_STAT || extra->d_type == _DTYPE_LSTAT) { - - const struct dirent_extra_stat * const extra_stat = - reinterpret_cast(extra); - - // Remember whether this was a link or not, this saves an lstat() call later. - if (extra->d_type == _DTYPE_LSTAT) { - knownFlagsMask |= QFileSystemMetaData::LinkType; - if (S_ISLNK(extra_stat->d_stat.st_mode)) - entryFlags |= QFileSystemMetaData::LinkType; - } - - // For symlinks, the extra type _DTYPE_LSTAT doesn't work for filling out the meta data, - // as we need the stat() information there, not the lstat() information. - // In this case, don't use the extra information. - // Unfortunately, readdir() never seems to return extra info of type _DTYPE_STAT, so for - // symlinks, we always incur the cost of an extra stat() call later. - if (S_ISLNK(extra_stat->d_stat.st_mode) && extra->d_type == _DTYPE_LSTAT) - continue; - -#if defined(QT_USE_XOPEN_LFS_EXTENSIONS) && defined(QT_LARGEFILE_SUPPORT) - // Even with large file support, d_stat is always of type struct stat, not struct stat64, - // so it needs to be converted - struct stat64 statBuf; - fillStat64fromStat32(&statBuf, extra_stat->d_stat); - fillFromStatBuf(statBuf); -#else - fillFromStatBuf(extra_stat->d_stat); -#endif - knownFlagsMask |= QFileSystemMetaData::PosixStatFlags; - if (!S_ISLNK(extra_stat->d_stat.st_mode)) { - knownFlagsMask |= QFileSystemMetaData::ExistsAttribute; - entryFlags |= QFileSystemMetaData::ExistsAttribute; - } - } - } -#elif defined(_DIRENT_HAVE_D_TYPE) || defined(Q_OS_BSD4) - // BSD4 includes OS X and iOS - - // ### This will clear all entry flags and knownFlagsMask - switch (entry.d_type) - { - case DT_DIR: - knownFlagsMask = QFileSystemMetaData::LinkType - | QFileSystemMetaData::FileType - | QFileSystemMetaData::DirectoryType - | QFileSystemMetaData::SequentialType - | QFileSystemMetaData::ExistsAttribute; - - entryFlags = QFileSystemMetaData::DirectoryType - | QFileSystemMetaData::ExistsAttribute; - - break; - - case DT_BLK: - knownFlagsMask = QFileSystemMetaData::LinkType - | QFileSystemMetaData::FileType - | QFileSystemMetaData::DirectoryType - | QFileSystemMetaData::BundleType - | QFileSystemMetaData::AliasType - | QFileSystemMetaData::SequentialType - | QFileSystemMetaData::ExistsAttribute; - - entryFlags = QFileSystemMetaData::ExistsAttribute; - - break; - - case DT_CHR: - case DT_FIFO: - case DT_SOCK: - // ### System attribute - knownFlagsMask = QFileSystemMetaData::LinkType - | QFileSystemMetaData::FileType - | QFileSystemMetaData::DirectoryType - | QFileSystemMetaData::BundleType - | QFileSystemMetaData::AliasType - | QFileSystemMetaData::SequentialType - | QFileSystemMetaData::ExistsAttribute; - - entryFlags = QFileSystemMetaData::SequentialType - | QFileSystemMetaData::ExistsAttribute; - - break; - - case DT_LNK: - knownFlagsMask = QFileSystemMetaData::LinkType; - entryFlags = QFileSystemMetaData::LinkType; - break; - - case DT_REG: - knownFlagsMask = QFileSystemMetaData::LinkType - | QFileSystemMetaData::FileType - | QFileSystemMetaData::DirectoryType - | QFileSystemMetaData::BundleType - | QFileSystemMetaData::SequentialType - | QFileSystemMetaData::ExistsAttribute; - - entryFlags = QFileSystemMetaData::FileType - | QFileSystemMetaData::ExistsAttribute; - - break; - - case DT_UNKNOWN: - default: - clear(); - } -#else - Q_UNUSED(entry) -#endif -} - -#endif - //static QString QFileSystemEngine::resolveUserName(const QFileSystemEntry &entry, QFileSystemMetaData &metaData) { diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 0b16c62f76..e64c7542dd 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -195,6 +195,224 @@ static inline typename QtPrivate::QEnableIf<(&T::st_atimensec, &T::st_mtimensec, } #endif +//static +bool QFileSystemEngine::fillMetaData(int fd, QFileSystemMetaData &data) +{ + data.entryFlags &= ~QFileSystemMetaData::PosixStatFlags; + data.knownFlagsMask |= QFileSystemMetaData::PosixStatFlags; + + QT_STATBUF statBuffer; + if (QT_FSTAT(fd, &statBuffer) == 0) { + data.fillFromStatBuf(statBuffer); + return true; + } + + return false; +} + +#if defined(_DEXTRA_FIRST) +static void fillStat64fromStat32(struct stat64 *statBuf64, const struct stat &statBuf32) +{ + statBuf64->st_mode = statBuf32.st_mode; + statBuf64->st_size = statBuf32.st_size; +#if _POSIX_VERSION >= 200809L + statBuf64->st_ctim = statBuf32.st_ctim; + statBuf64->st_mtim = statBuf32.st_mtim; + statBuf64->st_atim = statBuf32.st_atim; +#else + statBuf64->st_ctime = statBuf32.st_ctime; + statBuf64->st_mtime = statBuf32.st_mtime; + statBuf64->st_atime = statBuf32.st_atime; +#endif + statBuf64->st_uid = statBuf32.st_uid; + statBuf64->st_gid = statBuf32.st_gid; +} +#endif + +#if _POSIX_VERSION >= 200809L +static qint64 timespecToMSecs(const timespec &spec) +{ + return (qint64(spec.tv_sec) * 1000) + (spec.tv_nsec / 1000000); +} +#endif + +void QFileSystemMetaData::fillFromStatBuf(const QT_STATBUF &statBuffer) +{ + // Permissions + if (statBuffer.st_mode & S_IRUSR) + entryFlags |= QFileSystemMetaData::OwnerReadPermission; + if (statBuffer.st_mode & S_IWUSR) + entryFlags |= QFileSystemMetaData::OwnerWritePermission; + if (statBuffer.st_mode & S_IXUSR) + entryFlags |= QFileSystemMetaData::OwnerExecutePermission; + + if (statBuffer.st_mode & S_IRGRP) + entryFlags |= QFileSystemMetaData::GroupReadPermission; + if (statBuffer.st_mode & S_IWGRP) + entryFlags |= QFileSystemMetaData::GroupWritePermission; + if (statBuffer.st_mode & S_IXGRP) + entryFlags |= QFileSystemMetaData::GroupExecutePermission; + + if (statBuffer.st_mode & S_IROTH) + entryFlags |= QFileSystemMetaData::OtherReadPermission; + if (statBuffer.st_mode & S_IWOTH) + entryFlags |= QFileSystemMetaData::OtherWritePermission; + if (statBuffer.st_mode & S_IXOTH) + entryFlags |= QFileSystemMetaData::OtherExecutePermission; + + // Type + if ((statBuffer.st_mode & S_IFMT) == S_IFREG) + entryFlags |= QFileSystemMetaData::FileType; + else if ((statBuffer.st_mode & S_IFMT) == S_IFDIR) + entryFlags |= QFileSystemMetaData::DirectoryType; + else if ((statBuffer.st_mode & S_IFMT) != S_IFBLK) + entryFlags |= QFileSystemMetaData::SequentialType; + + // Attributes + 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) { + entryFlags |= QFileSystemMetaData::HiddenAttribute; + knownFlagsMask |= QFileSystemMetaData::HiddenAttribute; + } +#endif + + // Times + birthTime_ = 0; +#if _POSIX_VERSION >= 200809L + modificationTime_ = timespecToMSecs(statBuffer.st_mtim); + metadataChangeTime_ = timespecToMSecs(statBuffer.st_ctim); + accessTime_ = timespecToMSecs(statBuffer.st_atim); +#else + modificationTime_ = qint64(statBuffer.st_mtime) * 1000; + metadataChangeTime_ = qint64(statBuffer.st_ctime) * 1000; + accessTime_ = qint64(statBuffer.st_atime) * 1000; +#endif + userId_ = statBuffer.st_uid; + groupId_ = statBuffer.st_gid; +} + +void QFileSystemMetaData::fillFromDirEnt(const QT_DIRENT &entry) +{ +#if defined(_DEXTRA_FIRST) + knownFlagsMask = 0; + entryFlags = 0; + for (dirent_extra *extra = _DEXTRA_FIRST(&entry); _DEXTRA_VALID(extra, &entry); + extra = _DEXTRA_NEXT(extra)) { + if (extra->d_type == _DTYPE_STAT || extra->d_type == _DTYPE_LSTAT) { + + const struct dirent_extra_stat * const extra_stat = + reinterpret_cast(extra); + + // Remember whether this was a link or not, this saves an lstat() call later. + if (extra->d_type == _DTYPE_LSTAT) { + knownFlagsMask |= QFileSystemMetaData::LinkType; + if (S_ISLNK(extra_stat->d_stat.st_mode)) + entryFlags |= QFileSystemMetaData::LinkType; + } + + // For symlinks, the extra type _DTYPE_LSTAT doesn't work for filling out the meta data, + // as we need the stat() information there, not the lstat() information. + // In this case, don't use the extra information. + // Unfortunately, readdir() never seems to return extra info of type _DTYPE_STAT, so for + // symlinks, we always incur the cost of an extra stat() call later. + if (S_ISLNK(extra_stat->d_stat.st_mode) && extra->d_type == _DTYPE_LSTAT) + continue; + +#if defined(QT_USE_XOPEN_LFS_EXTENSIONS) && defined(QT_LARGEFILE_SUPPORT) + // Even with large file support, d_stat is always of type struct stat, not struct stat64, + // so it needs to be converted + struct stat64 statBuf; + fillStat64fromStat32(&statBuf, extra_stat->d_stat); + fillFromStatBuf(statBuf); +#else + fillFromStatBuf(extra_stat->d_stat); +#endif + knownFlagsMask |= QFileSystemMetaData::PosixStatFlags; + if (!S_ISLNK(extra_stat->d_stat.st_mode)) { + knownFlagsMask |= QFileSystemMetaData::ExistsAttribute; + entryFlags |= QFileSystemMetaData::ExistsAttribute; + } + } + } +#elif defined(_DIRENT_HAVE_D_TYPE) || defined(Q_OS_BSD4) + // BSD4 includes OS X and iOS + + // ### This will clear all entry flags and knownFlagsMask + switch (entry.d_type) + { + case DT_DIR: + knownFlagsMask = QFileSystemMetaData::LinkType + | QFileSystemMetaData::FileType + | QFileSystemMetaData::DirectoryType + | QFileSystemMetaData::SequentialType + | QFileSystemMetaData::ExistsAttribute; + + entryFlags = QFileSystemMetaData::DirectoryType + | QFileSystemMetaData::ExistsAttribute; + + break; + + case DT_BLK: + knownFlagsMask = QFileSystemMetaData::LinkType + | QFileSystemMetaData::FileType + | QFileSystemMetaData::DirectoryType + | QFileSystemMetaData::BundleType + | QFileSystemMetaData::AliasType + | QFileSystemMetaData::SequentialType + | QFileSystemMetaData::ExistsAttribute; + + entryFlags = QFileSystemMetaData::ExistsAttribute; + + break; + + case DT_CHR: + case DT_FIFO: + case DT_SOCK: + // ### System attribute + knownFlagsMask = QFileSystemMetaData::LinkType + | QFileSystemMetaData::FileType + | QFileSystemMetaData::DirectoryType + | QFileSystemMetaData::BundleType + | QFileSystemMetaData::AliasType + | QFileSystemMetaData::SequentialType + | QFileSystemMetaData::ExistsAttribute; + + entryFlags = QFileSystemMetaData::SequentialType + | QFileSystemMetaData::ExistsAttribute; + + break; + + case DT_LNK: + knownFlagsMask = QFileSystemMetaData::LinkType; + entryFlags = QFileSystemMetaData::LinkType; + break; + + case DT_REG: + knownFlagsMask = QFileSystemMetaData::LinkType + | QFileSystemMetaData::FileType + | QFileSystemMetaData::DirectoryType + | QFileSystemMetaData::BundleType + | QFileSystemMetaData::SequentialType + | QFileSystemMetaData::ExistsAttribute; + + entryFlags = QFileSystemMetaData::FileType + | QFileSystemMetaData::ExistsAttribute; + + break; + + case DT_UNKNOWN: + default: + clear(); + } +#else + Q_UNUSED(entry) +#endif +} + //static QFileSystemEntry QFileSystemEngine::getLinkTarget(const QFileSystemEntry &link, QFileSystemMetaData &data) {