Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qstorageinfo_linux.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// Copyright (C) 2014 Ivan Komissarov <ABBAPOH@gmail.com>
3// Copyright (C) 2016 Intel Corporation.
4// Copyright (C) 2023 Ahmad Samir <a.samirh78@gmail.com>
5// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
6
8
9#include "qdiriterator.h"
10#include <private/qcore_unix_p.h>
11
12#if defined(Q_OS_ANDROID)
13# include <sys/mount.h>
14# include <sys/vfs.h>
15# define QT_STATFS ::statfs
16# define QT_STATFSBUF struct statfs
17# if !defined(ST_RDONLY)
18# define ST_RDONLY 1 // hack for missing define on Android
19# endif
20#else
21# include <sys/statvfs.h>
22# if defined(QT_LARGEFILE_SUPPORT)
23# define QT_STATFSBUF struct statvfs64
24# define QT_STATFS ::statvfs64
25# else
26# define QT_STATFSBUF struct statvfs
27# define QT_STATFS ::statvfs
28# endif // QT_LARGEFILE_SUPPORT
29#endif
30
32
33using namespace Qt::StringLiterals;
34
35// udev encodes the labels with ID_LABEL_FS_ENC which is done with
36// blkid_encode_string(). Within this function some 1-byte utf-8
37// characters not considered safe (e.g. '\' or ' ') are encoded as hex
39{
40 QString decoded;
41 decoded.reserve(str.size());
42
43 int i = 0;
44 while (i < str.size()) {
45 if (i <= str.size() - 4) { // we need at least four characters \xAB
46 if (QStringView{str}.sliced(i).startsWith("\\x"_L1)) {
47 bool bOk;
48 const int code = QStringView{str}.mid(i+2, 2).toInt(&bOk, 16);
49 if (bOk && code >= 0x20 && code < 0x80) {
50 decoded += QChar(code);
51 i += 4;
52 continue;
53 }
54 }
55 }
56 decoded += str.at(i);
57 ++i;
58 }
59 return decoded;
60}
61
63{
64 static const char pathDiskByLabel[] = "/dev/disk/by-label";
65
67 QString devicePath = devinfo.canonicalFilePath();
68
70 while (it.hasNext()) {
71 QFileInfo fileInfo = it.nextFileInfo();
72 if (fileInfo.isSymLink() && fileInfo.symLinkTarget() == devicePath)
73 return decodeFsEncString(fileInfo.fileName());
74 }
75 return QString();
76}
77
78void QStorageInfoPrivate::doStat()
79{
80 initRootPath();
81 if (rootPath.isEmpty())
82 return;
83
84 retrieveVolumeInfo();
86}
87
88void QStorageInfoPrivate::retrieveVolumeInfo()
89{
90 QT_STATFSBUF statfs_buf;
91 int result;
92 EINTR_LOOP(result, QT_STATFS(QFile::encodeName(rootPath).constData(), &statfs_buf));
93 if (result == 0) {
94 valid = true;
95 ready = true;
96
97 bytesTotal = statfs_buf.f_blocks * statfs_buf.f_frsize;
98 bytesFree = statfs_buf.f_bfree * statfs_buf.f_frsize;
99 bytesAvailable = statfs_buf.f_bavail * statfs_buf.f_frsize;
100 blockSize = statfs_buf.f_bsize;
101
102#if defined(Q_OS_ANDROID)
103#if defined(_STATFS_F_FLAGS)
104 readOnly = (statfs_buf.f_flags & ST_RDONLY) != 0;
105#endif
106#else
107 readOnly = (statfs_buf.f_flag & ST_RDONLY) != 0;
108#endif
109 }
110}
111
113{
114 QFile file(u"/proc/self/mountinfo"_s);
116 return {};
117
118 QByteArray mountinfo = file.readAll();
119 file.close();
120
121 return doParseMountInfo(mountinfo, filter);
122}
123
124void QStorageInfoPrivate::initRootPath()
125{
126 rootPath = QFileInfo(rootPath).canonicalFilePath();
127 if (rootPath.isEmpty())
128 return;
129
130 std::vector<MountInfo> infos = parseMountInfo();
131 if (infos.empty()) {
132 rootPath = u'/';
133 return;
134 }
135
137 const QString oldRootPath = rootPath;
138 rootPath.clear();
139
140 for (auto &info : infos) {
141 // we try to find most suitable entry
142 qsizetype mpSize = info.mountPoint.size();
143 if (isParentOf(info.mountPoint, oldRootPath) && maxLength < mpSize) {
144 maxLength = mpSize;
145 rootPath = info.mountPoint;
146 device = info.device;
147 fileSystemType = info.fsType;
148 subvolume = info.fsRoot;
149 }
150 }
151}
152
153QList<QStorageInfo> QStorageInfoPrivate::mountedVolumes()
154{
155 std::vector<MountInfo> infos = parseMountInfo(FilterMountInfo::Filtered);
156 if (infos.empty())
157 return QList{root()};
158
159 QList<QStorageInfo> volumes;
160 for (MountInfo &info : infos) {
161 QStorageInfo storage(info.mountPoint);
162 storage.d->device = info.device;
163 storage.d->fileSystemType = info.fsType;
164 storage.d->subvolume = info.fsRoot;
165 if (storage.bytesTotal() == 0 && storage != root())
166 continue;
167 volumes.push_back(storage);
168 }
169 return volumes;
170}
171
IOBluetoothDevice * device
\inmodule QtCore
Definition qbytearray.h:57
\inmodule QtCore
Definition qchar.h:48
The QDirIterator class provides an iterator for directory entrylists.
@ NoDotAndDotDot
Definition qdir.h:43
void close() override
Calls QFileDevice::flush() and closes the file.
\inmodule QtCore \reentrant
Definition qfileinfo.h:22
bool isSymLink() const
Returns true if this object points to a symbolic link, shortcut, or alias; otherwise returns false.
QString symLinkTarget() const
QString fileName() const
Returns the name of the file, excluding the path.
qint64 size() const
Returns the file size in bytes.
QString canonicalFilePath() const
Returns the canonical path including the file name, i.e.
\inmodule QtCore
Definition qfile.h:93
bool open(OpenMode flags) override
Opens the file using OpenMode mode, returning true if successful; otherwise false.
Definition qfile.cpp:881
static QByteArray encodeName(const QString &fileName)
Converts fileName to an 8-bit encoding that you can use in native APIs.
Definition qfile.h:158
static QString decodeName(const QByteArray &localFileName)
This does the reverse of QFile::encodeName() using localFileName.
Definition qfile.h:162
QByteArray readAll()
Reads all remaining data from the device, and returns it as a byte array.
Definition qlist.h:74
void push_back(parameter_type t)
Definition qlist.h:672
\inmodule QtCore
qint64 bytesTotal() const
Returns the total volume size in bytes.
\inmodule QtCore
Definition qstringview.h:76
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
int toInt(bool *ok=nullptr, int base=10) const
Returns the string converted to an int using base base, which is 10 by default and must be between 2 ...
Definition qstring.h:660
void reserve(qsizetype size)
Ensures the string has space for at least size characters.
Definition qstring.h:1173
void clear()
Clears the contents of the string and makes it null.
Definition qstring.h:1107
qsizetype size() const
Returns the number of characters in this string.
Definition qstring.h:182
QString mid(qsizetype position, qsizetype n=-1) const
Returns a string that contains n characters of this string, starting at the specified position index.
Definition qstring.cpp:5204
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
Definition qstring.h:1079
QString sliced(qsizetype pos) const
Definition qstring.h:341
QString str
[2]
QSet< QString >::iterator it
Combined button and popup list for selecting options.
const int blockSize
#define EINTR_LOOP(var, cmd)
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLuint name
GLsizei maxLength
GLuint64EXT * result
[6]
#define QT_STATFS
static std::vector< MountInfo > parseMountInfo(FilterMountInfo filter=FilterMountInfo::All)
static QString retrieveLabel(const QByteArray &device)
static QString decodeFsEncString(const QString &str)
#define QT_STATFSBUF
static std::vector< MountInfo > doParseMountInfo(const QByteArray &mountinfo, FilterMountInfo filter=FilterMountInfo::All)
QT_BEGIN_NAMESPACE static Q_LOGGING_CATEGORY(lcStorageInfo, "qt.core.qstorageinfo", QtWarningMsg) class QStorageInfoPrivate bool isParentOf(const String &parent, const QString &dirName)
ptrdiff_t qsizetype
Definition qtypes.h:70
QFile file
[0]
QFileInfo info(fileName)
[8]
QStorageInfo storage
[1]