summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qstorageinfo_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/io/qstorageinfo_p.h')
-rw-r--r--src/corelib/io/qstorageinfo_p.h163
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