diff options
Diffstat (limited to 'src/corelib/io/qstorageinfo_p.h')
-rw-r--r-- | src/corelib/io/qstorageinfo_p.h | 163 |
1 files changed, 111 insertions, 52 deletions
diff --git a/src/corelib/io/qstorageinfo_p.h b/src/corelib/io/qstorageinfo_p.h index 421e364311..3af4b81ca4 100644 --- a/src/corelib/io/qstorageinfo_p.h +++ b/src/corelib/io/qstorageinfo_p.h @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Ivan Komissarov <ABBAPOH@gmail.com> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2014 Ivan Komissarov <ABBAPOH@gmail.com> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QSTORAGEINFO_P_H #define QSTORAGEINFO_P_H @@ -51,34 +15,77 @@ // We mean it. // +#include <QtCore/qloggingcategory.h> +#include <QtCore/qsystemdetection.h> +#include <QtCore/qtenvironmentvariables.h> #include <QtCore/private/qglobal_p.h> #include "qstorageinfo.h" +#ifdef Q_OS_UNIX +#include <sys/types.h> // dev_t +#endif + QT_BEGIN_NAMESPACE +inline Q_LOGGING_CATEGORY(lcStorageInfo, "qt.core.qstorageinfo", QtWarningMsg) + class QStorageInfoPrivate : public QSharedData { public: - inline QStorageInfoPrivate() : QSharedData(), - bytesTotal(-1), bytesFree(-1), bytesAvailable(-1), blockSize(-1), - readOnly(false), ready(false), valid(false) - {} + QStorageInfoPrivate() = default; - void initRootPath(); void doStat(); static QList<QStorageInfo> mountedVolumes(); - static QStorageInfo root(); + + static QStorageInfo root() + { +#ifdef Q_OS_WIN + return QStorageInfo(QDir::fromNativeSeparators(QFile::decodeName(qgetenv("SystemDrive")))); +#else + return QStorageInfo(QStringLiteral("/")); +#endif + }; protected: #if defined(Q_OS_WIN) + void initRootPath(); void retrieveVolumeInfo(); void retrieveDiskFreeSpace(); -#elif defined(Q_OS_MAC) + bool queryStorageProperty(); + void queryFileFsSectorSizeInformation(); +#elif defined(Q_OS_DARWIN) + void initRootPath(); void retrievePosixInfo(); void retrieveUrlProperties(bool initRootPath = false); void retrieveLabel(); +#elif defined(Q_OS_LINUX) + void retrieveVolumeInfo(); + +public: + struct MountInfo { + QString mountPoint; + QByteArray fsType; + QByteArray device; + QByteArray fsRoot; + dev_t stDev = 0; + }; + + void setFromMountInfo(MountInfo &&info) + { + rootPath = std::move(info.mountPoint); + fileSystemType = std::move(info.fsType); + device = std::move(info.device); + subvolume = std::move(info.fsRoot); + } + + QStorageInfoPrivate(MountInfo &&info) + { + setFromMountInfo(std::move(info)); + } + #elif defined(Q_OS_UNIX) + void initRootPath(); void retrieveVolumeInfo(); #endif @@ -89,16 +96,68 @@ public: QByteArray fileSystemType; QString name; - qint64 bytesTotal; - qint64 bytesFree; - qint64 bytesAvailable; - int blockSize; + qint64 bytesTotal = -1; + qint64 bytesFree = -1; + qint64 bytesAvailable = -1; + int blockSize = -1; - bool readOnly; - bool ready; - bool valid; + bool readOnly = false; + bool ready = false; + bool valid = false; }; +// Common helper functions +template <typename String> +static bool isParentOf(const String &parent, const QString &dirName) +{ + return dirName.startsWith(parent) && + (dirName.size() == parent.size() || dirName.at(parent.size()) == u'/' || + parent.size() == 1); +} + +static inline bool shouldIncludeFs(const QString &mountDir, const QByteArray &fsType) +{ +#if defined(Q_OS_ANDROID) + // "rootfs" is the filesystem type of "/" on Android + static constexpr char RootFsStr[] = ""; +#else + // "rootfs" is a type of ramfs on Linux, used in the initrd on some distros + static constexpr char RootFsStr[] = "rootfs"; +#endif + + using namespace Qt::StringLiterals; + /* + * This function implements a heuristic algorithm to determine whether a + * given mount should be reported to the user. Our objective is to list + * only entries that the end-user would find useful. + * + * We therefore ignore: + * - mounted in /dev, /proc, /sys: special mounts + * (this will catch /sys/fs/cgroup, /proc/sys/fs/binfmt_misc, /dev/pts, + * some of which are tmpfs on Linux) + * - mounted in /var/run or /var/lock: most likely pseudofs + * (on earlier systemd versions, /var/run was a bind-mount of /run, so + * everything would be unnecessarily duplicated) + * - filesystem type is "rootfs": artifact of the root-pivot on some Linux + * initrd + * - if the filesystem total size is zero, it's a pseudo-fs (not checked here). + */ + + if (isParentOf("/dev"_L1, mountDir) + || isParentOf("/proc"_L1, mountDir) + || isParentOf("/sys"_L1, mountDir) + || isParentOf("/var/run"_L1, mountDir) + || isParentOf("/var/lock"_L1, mountDir)) { + return false; + } + + if (!fsType.isEmpty() && fsType == RootFsStr) + return false; + + // size checking in QStorageInfo::mountedVolumes() + return true; +} + QT_END_NAMESPACE #endif // QSTORAGEINFO_P_H |