From 68fb365e826d441617af4754e7a9b53d0a67b3c2 Mon Sep 17 00:00:00 2001 From: Karim Pinter Date: Thu, 20 Mar 2025 11:08:45 +0200 Subject: [PATCH] Fix VxWorks POSIX access() behavior On VxWorks POSIX access() returns always false if it is called on file which is not on POSIX file system, like DOSFS for example. Qt for VxWorks 5.15 had similar patch omitting all access() calls and returning true. This fix takes it a step further and checks if the file is on POSIX filesystem or if it is DOSFS with read-only setting or not, in case omitting access() call and returning true. Failure became visible using QTranslator::load() method on DOSFS mmc card. Task-number: QTBUG-134627 Pick-to: 6.8 Change-Id: I9c257d3cba1a2b976f2775ad129aae0e09f68ffd Reviewed-by: Thiago Macieira (cherry picked from commit fd73b220897e5b6faf012f2812e7eb9eab6c3955) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/io/qfilesystemengine_unix.cpp | 44 +++++++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 5c5bd15f71b..240e496f591 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -69,6 +69,13 @@ #endif #endif +#if defined(Q_OS_VXWORKS) +# include +# if __has_include() +# include +# endif +#endif + #if defined(Q_OS_ANDROID) // statx() is disabled on Android because quite a few systems // come with sandboxes that kill applications that make system calls outside a @@ -331,8 +338,15 @@ flagsFromStMode(mode_t mode, [[maybe_unused]] quint64 attributes) #ifdef UF_HIDDEN if (attributes & UF_HIDDEN) entryFlags |= QFileSystemMetaData::HiddenAttribute; +#elif defined(Q_OS_VXWORKS) && __has_include() + if (attributes & DOS_ATTR_RDONLY) { + // on a DOS FS, stat() always returns 0777 bits set in st_mode + // when DOS FS is read only the write permissions are removed + entryFlags &= ~QFileSystemMetaData::OwnerWritePermission; + entryFlags &= ~QFileSystemMetaData::GroupWritePermission; + entryFlags &= ~QFileSystemMetaData::OtherWritePermission; + } #endif - return entryFlags; } @@ -476,8 +490,9 @@ void QFileSystemMetaData::fillFromStatBuf(const QT_STATBUF &statBuffer) quint64 attributes = 0; #if defined(UF_SETTABLE) // BSDs (incl. Darwin) attributes = statBuffer.st_flags; +#elif defined(Q_OS_VXWORKS) && __has_include() + attributes = statBuffer.st_attrib; #endif - // Permissions MetaDataFlags flags = flagsFromStMode(statBuffer.st_mode, attributes); entryFlags |= flags; @@ -990,6 +1005,30 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM // third, we try access(2) if (what & (QFileSystemMetaData::UserPermissions | QFileSystemMetaData::ExistsAttribute)) { +#if defined(Q_OS_VXWORKS) + // on VxWorks if the filesystem is not POSIX, access() always returns false, despite the + // file is readable + struct statfs statBuf; + if (statfs(nativeFilePath, &statBuf) != 0) { + what &= ~QFileSystemMetaData::LinkType; // don't clear link: could be broken symlink + data.clearFlags(what); + return false; + } + if (statBuf.f_type != NFSV2_MAGIC && statBuf.f_type != NFSV3_MAGIC && + statBuf.f_type != HRFS_MAGIC) { +#if __has_include() + if (data.entryFlags & QFileSystemMetaData::OwnerWritePermission) { + data.entryFlags |= QFileSystemMetaData::UserWritePermission; + } + if (data.entryFlags & QFileSystemMetaData::OwnerExecutePermission) { + data.entryFlags |= QFileSystemMetaData::UserExecutePermission; + } +#endif + data.entryFlags |= QFileSystemMetaData::UserReadPermission | + QFileSystemMetaData::ExistsAttribute; + return true; + } +#endif // calculate user permissions auto checkAccess = [&](QFileSystemMetaData::MetaDataFlag flag, int mode) { if (entryErrno != 0 || (what & flag) == 0) @@ -1001,7 +1040,6 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM entryErrno = errno; } }; - checkAccess(QFileSystemMetaData::UserReadPermission, R_OK); checkAccess(QFileSystemMetaData::UserWritePermission, W_OK); checkAccess(QFileSystemMetaData::UserExecutePermission, X_OK);