1// Copyright (C) 2014 Ivan Komissarov <ABBAPOH@gmail.com>
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QSTORAGEINFO_P_H
5#define QSTORAGEINFO_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtCore/qloggingcategory.h>
19#include <QtCore/qsystemdetection.h>
20#include <QtCore/qtenvironmentvariables.h>
21#include <QtCore/private/qglobal_p.h>
22#include "qstorageinfo.h"
23
24#ifdef Q_OS_UNIX
25#include <sys/types.h> // dev_t
26#endif
27
28QT_BEGIN_NAMESPACE
29
30inline Q_LOGGING_CATEGORY(lcStorageInfo, "qt.core.qstorageinfo", QtWarningMsg)
31
32class QStorageInfoPrivate : public QSharedData
33{
34public:
35 QStorageInfoPrivate() = default;
36
37 void doStat();
38
39 static QList<QStorageInfo> mountedVolumes();
40
41 static QStorageInfo root()
42 {
43#ifdef Q_OS_WIN
44 return QStorageInfo(QDir::fromNativeSeparators(QFile::decodeName(qgetenv("SystemDrive"))));
45#else
46 return QStorageInfo(QStringLiteral("/"));
47#endif
48 };
49
50protected:
51#if defined(Q_OS_WIN)
52 void initRootPath();
53 void retrieveVolumeInfo();
54 void retrieveDiskFreeSpace();
55 bool queryStorageProperty();
56 void queryFileFsSectorSizeInformation();
57#elif defined(Q_OS_DARWIN)
58 void initRootPath();
59 void retrievePosixInfo();
60 void retrieveUrlProperties(bool initRootPath = false);
61 void retrieveLabel();
62#elif defined(Q_OS_LINUX)
63 void retrieveVolumeInfo();
64
65public:
66 struct MountInfo {
67 QString mountPoint;
68 QByteArray fsType;
69 QByteArray device;
70 QByteArray fsRoot;
71 dev_t stDev = 0;
72 quint64 mntid = 0;
73 };
74
75 void setFromMountInfo(MountInfo &&info)
76 {
77 rootPath = std::move(info.mountPoint);
78 fileSystemType = std::move(info.fsType);
79 device = std::move(info.device);
80 subvolume = std::move(info.fsRoot);
81 }
82
83 QStorageInfoPrivate(MountInfo &&info)
84 {
85 setFromMountInfo(std::move(info));
86 }
87
88#elif defined(Q_OS_UNIX)
89 void initRootPath();
90 void retrieveVolumeInfo();
91#endif
92
93#ifdef Q_OS_UNIX
94 // Common helper functions
95 template <typename String>
96 static bool isParentOf(const String &parent, const QString &dirName)
97 {
98 return dirName.startsWith(parent) &&
99 (dirName.size() == parent.size() || dirName.at(i: parent.size()) == u'/' ||
100 parent.size() == 1);
101 }
102 static inline bool shouldIncludeFs(const QString &mountDir, const QByteArray &fsType);
103#endif
104
105public:
106 QString rootPath;
107 QByteArray device;
108 QByteArray subvolume;
109 QByteArray fileSystemType;
110 QString name;
111
112 qint64 bytesTotal = -1;
113 qint64 bytesFree = -1;
114 qint64 bytesAvailable = -1;
115 int blockSize = -1;
116
117 bool readOnly = false;
118 bool ready = false;
119 bool valid = false;
120};
121
122#ifdef Q_OS_UNIX
123bool QStorageInfoPrivate::shouldIncludeFs(const QString &mountDir, const QByteArray &fsType)
124{
125#if defined(Q_OS_ANDROID)
126 // "rootfs" is the filesystem type of "/" on Android
127 static constexpr char RootFsStr[] = "";
128#else
129 // "rootfs" is a type of ramfs on Linux, used in the initrd on some distros
130 static constexpr char RootFsStr[] = "rootfs";
131#endif
132
133 using namespace Qt::StringLiterals;
134 /*
135 * This function implements a heuristic algorithm to determine whether a
136 * given mount should be reported to the user. Our objective is to list
137 * only entries that the end-user would find useful.
138 *
139 * We therefore ignore:
140 * - mounted in /dev, /proc, /sys: special mounts
141 * (this will catch /sys/fs/cgroup, /proc/sys/fs/binfmt_misc, /dev/pts,
142 * some of which are tmpfs on Linux)
143 * - mounted in /var/run or /var/lock: most likely pseudofs
144 * (on earlier systemd versions, /var/run was a bind-mount of /run, so
145 * everything would be unnecessarily duplicated)
146 * - filesystem type is "rootfs": artifact of the root-pivot on some Linux
147 * initrd
148 * - if the filesystem total size is zero, it's a pseudo-fs (not checked here).
149 */
150
151 if (isParentOf(parent: "/dev"_L1, dirName: mountDir)
152 || isParentOf(parent: "/proc"_L1, dirName: mountDir)
153 || isParentOf(parent: "/sys"_L1, dirName: mountDir)
154 || isParentOf(parent: "/var/run"_L1, dirName: mountDir)
155 || isParentOf(parent: "/var/lock"_L1, dirName: mountDir)) {
156 return false;
157 }
158
159 if (!fsType.isEmpty() && fsType == RootFsStr)
160 return false;
161
162 // size checking in QStorageInfo::mountedVolumes()
163 return true;
164}
165#endif // Q_OS_UNIX
166
167QT_END_NAMESPACE
168
169#endif // QSTORAGEINFO_P_H
170

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of qtbase/src/corelib/io/qstorageinfo_p.h