QStorageInfo/Linux: switch the non-Android version to also use statfs()

It's the actual system call on Linux, inspired by the 4.4BSD call of the
same name (and our BSD code also uses statfs(), except for NetBSD, but
it probably could use statfs() there too). statvfs() wasn't introduced
until POSIX.1-2001, though glibc added it in 1998 for version 2.1 and
Bionic only for NDK version 19 in 2019.

So we could merge the Android code to the POSIX version, but it's easier
to merge the non-Android code to the raw system call.

Change-Id: I8f3ce163ccc5408cac39fffd178dbd83567a78d5
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
Thiago Macieira 2023-10-13 11:16:46 -07:00
parent 6e21d1d21a
commit b3eb951d18
3 changed files with 10 additions and 28 deletions

View File

@ -10,24 +10,8 @@
#include <private/qcore_unix_p.h> #include <private/qcore_unix_p.h>
#include <private/qtools_p.h> #include <private/qtools_p.h>
#if defined(Q_OS_ANDROID) #include <sys/mount.h>
# include <sys/mount.h> #include <sys/statfs.h>
# include <sys/vfs.h>
# define QT_STATFS ::statfs
# define QT_STATFSBUF struct statfs
# if !defined(ST_RDONLY)
# define ST_RDONLY 1 // hack for missing define on Android
# endif
#else
# include <sys/statvfs.h>
# if defined(QT_LARGEFILE_SUPPORT)
# define QT_STATFSBUF struct statvfs64
# define QT_STATFS ::statvfs64
# else
# define QT_STATFSBUF struct statvfs
# define QT_STATFS ::statvfs
# endif // QT_LARGEFILE_SUPPORT
#endif
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -160,9 +144,9 @@ void QStorageInfoPrivate::doStat()
void QStorageInfoPrivate::retrieveVolumeInfo() void QStorageInfoPrivate::retrieveVolumeInfo()
{ {
QT_STATFSBUF statfs_buf; struct statfs64 statfs_buf;
int result; int result;
EINTR_LOOP(result, QT_STATFS(QFile::encodeName(rootPath).constData(), &statfs_buf)); EINTR_LOOP(result, statfs64(QFile::encodeName(rootPath).constData(), &statfs_buf));
if (result == 0) { if (result == 0) {
valid = true; valid = true;
ready = true; ready = true;
@ -171,14 +155,7 @@ void QStorageInfoPrivate::retrieveVolumeInfo()
bytesFree = statfs_buf.f_bfree * statfs_buf.f_frsize; bytesFree = statfs_buf.f_bfree * statfs_buf.f_frsize;
bytesAvailable = statfs_buf.f_bavail * statfs_buf.f_frsize; bytesAvailable = statfs_buf.f_bavail * statfs_buf.f_frsize;
blockSize = int(statfs_buf.f_bsize); blockSize = int(statfs_buf.f_bsize);
readOnly = (statfs_buf.f_flags & MS_RDONLY) != 0;
#if defined(Q_OS_ANDROID)
#if defined(_STATFS_F_FLAGS)
readOnly = (statfs_buf.f_flags & ST_RDONLY) != 0;
#endif
#else
readOnly = (statfs_buf.f_flag & ST_RDONLY) != 0;
#endif
} }
} }

View File

@ -16,4 +16,5 @@ qt_internal_add_test(tst_qstorageinfo
tst_qstorageinfo.cpp tst_qstorageinfo.cpp
LIBRARIES LIBRARIES
Qt::CorePrivate Qt::CorePrivate
Qt::TestPrivate
) )

View File

@ -6,6 +6,7 @@
#include <QStandardPaths> #include <QStandardPaths>
#include <QStorageInfo> #include <QStorageInfo>
#include <QTemporaryFile> #include <QTemporaryFile>
#include "private/qemulationdetector_p.h"
#include <stdarg.h> #include <stdarg.h>
@ -148,6 +149,9 @@ void tst_QStorageInfo::currentStorage()
void tst_QStorageInfo::storageList_data() void tst_QStorageInfo::storageList_data()
{ {
if (QTestPrivate::isRunningArmOnX86())
QSKIP("QEMU appears not to emulate the system calls correctly.");
QStorageInfo root = QStorageInfo::root(); QStorageInfo root = QStorageInfo::root();
QList<QStorageInfo> volumes = QStorageInfo::mountedVolumes(); QList<QStorageInfo> volumes = QStorageInfo::mountedVolumes();