9#include <QtCore/qfileinfo.h>
10#include <QtCore/qtextstream.h>
12#include <QtCore/private/qcore_unix_p.h>
13#include <QtCore/private/qlocale_tools_p.h>
19# include <sys/mount.h>
20# include <sys/statvfs.h>
21#elif defined(Q_OS_HURD)
23# include <sys/statvfs.h>
24# include <sys/sysmacros.h>
25#elif defined(Q_OS_SOLARIS)
26# include <sys/mnttab.h>
27# include <sys/statvfs.h>
28#elif defined(Q_OS_HAIKU)
29# include <Directory.h>
32# include <VolumeRoster.h>
34# include <sys/statvfs.h>
36# include <sys/statvfs.h>
40# if defined(Q_OS_NETBSD)
41# define QT_STATFSBUF struct statvfs
42# define QT_STATFS ::statvfs
44# define QT_STATFSBUF struct statfs
45# define QT_STATFS ::statfs
48# if !defined(ST_RDONLY)
49# define ST_RDONLY MNT_RDONLY
51# if !defined(_STATFS_F_FLAGS) && !defined(Q_OS_NETBSD)
52# define _STATFS_F_FLAGS 1
54#elif defined(Q_OS_HAIKU) || defined(Q_OS_CYGWIN)
55# define QT_STATFSBUF struct statvfs
56# define QT_STATFS ::statvfs
58# if defined(QT_LARGEFILE_SUPPORT)
59# define QT_STATFSBUF struct statvfs64
60# define QT_STATFS ::statvfs64
62# define QT_STATFSBUF struct statvfs
63# define QT_STATFS ::statvfs
71# define _PATH_MOUNTED "/etc/mnttab"
76using namespace Qt::StringLiterals;
96#elif defined(Q_OS_SOLARIS)
99#elif defined(Q_OS_HURD)
103#elif defined(Q_OS_HAIKU)
112#if defined(Q_OS_BSD4)
118inline QStorageIterator::QStorageIterator()
119 : entryCount(::getmntinfo(&stat_buf, MNT_NOWAIT)),
124inline QStorageIterator::~QStorageIterator()
128inline bool QStorageIterator::isValid()
const
130 return entryCount != -1;
133inline bool QStorageIterator::next()
135 return ++currentIndex < entryCount;
138inline QString QStorageIterator::rootPath()
const
140 return QFile::decodeName(stat_buf[currentIndex].f_mntonname);
143inline QByteArray QStorageIterator::fileSystemType()
const
145 return QByteArray(stat_buf[currentIndex].f_fstypename);
148inline QByteArray QStorageIterator::device()
const
150 return QByteArray(stat_buf[currentIndex].f_mntfromname);
153inline QByteArray QStorageIterator::options()
const
158inline QByteArray QStorageIterator::subvolume()
const
162#elif defined(Q_OS_SOLARIS)
164inline QStorageIterator::QStorageIterator()
166 const int fd = qt_safe_open(_PATH_MOUNTED, O_RDONLY);
167 fp = ::fdopen(fd,
"r");
170inline QStorageIterator::~QStorageIterator()
176inline bool QStorageIterator::isValid()
const
178 return fp !=
nullptr;
181inline bool QStorageIterator::next()
183 return ::getmntent(fp, &mnt) == 0;
186inline QString QStorageIterator::rootPath()
const
188 return QFile::decodeName(mnt.mnt_mountp);
191inline QByteArray QStorageIterator::fileSystemType()
const
193 return QByteArray(mnt.mnt_fstype);
196inline QByteArray QStorageIterator::device()
const
198 return QByteArray(mnt.mnt_mntopts);
201inline QByteArray QStorageIterator::subvolume()
const
206#elif defined(Q_OS_HURD)
208static const int bufferSize = 1024;
211inline QStorageIterator::QStorageIterator() :
212 buffer(QByteArray(bufferSize, 0))
214 fp = ::setmntent(_PATH_MOUNTED,
"r");
217inline QStorageIterator::~QStorageIterator()
223inline bool QStorageIterator::isValid()
const
225 return fp !=
nullptr;
228inline bool QStorageIterator::next()
230 return ::getmntent_r(fp, &mnt, buffer.data(), buffer.size()) !=
nullptr;
233inline QString QStorageIterator::rootPath()
const
235 return QFile::decodeName(mnt.mnt_dir);
238inline QByteArray QStorageIterator::fileSystemType()
const
240 return QByteArray(mnt.mnt_type);
243inline QByteArray QStorageIterator::device()
const
245 return QByteArray(mnt.mnt_fsname);
248inline QByteArray QStorageIterator::options()
const
250 return QByteArray(mnt.mnt_opts);
253inline QByteArray QStorageIterator::subvolume()
const
257#elif defined(Q_OS_HAIKU)
258inline QStorageIterator::QStorageIterator()
262inline QStorageIterator::~QStorageIterator()
266inline bool QStorageIterator::isValid()
const
271inline bool QStorageIterator::next()
275 if (m_volumeRoster.GetNextVolume(&volume) != B_OK)
278 BDirectory directory;
279 if (volume.GetRootDirectory(&directory) != B_OK)
282 const BPath path(&directory);
285 memset(&fsInfo, 0,
sizeof(fsInfo));
287 if (fs_stat_dev(volume.Device(), &fsInfo) != 0)
290 m_rootPath = path.Path();
291 m_fileSystemType = QByteArray(fsInfo.fsh_name);
293 const QByteArray deviceName(fsInfo.device_name);
294 m_device = (deviceName.isEmpty() ? QByteArray::number(qint32(volume.Device())) : deviceName);
299inline QString QStorageIterator::rootPath()
const
301 return QFile::decodeName(m_rootPath);
304inline QByteArray QStorageIterator::fileSystemType()
const
306 return m_fileSystemType;
309inline QByteArray QStorageIterator::device()
const
314inline QByteArray QStorageIterator::options()
const
319inline QByteArray QStorageIterator::subvolume()
const
372#if defined Q_OS_HAIKU
374 memset(&fsInfo, 0,
sizeof(fsInfo));
378 while ((dev = next_dev(&pos)) >= 0) {
379 if (fs_stat_dev(dev, &fsInfo) != 0)
382 if (qstrcmp(fsInfo.device_name, device.constData()) == 0)
383 return QString::fromLocal8Bit(fsInfo.volume_name);
392void QStorageInfoPrivate::doStat()
394 valid = ready =
false;
396 if (rootPath.isEmpty())
399 retrieveVolumeInfo();
400 name = retrieveLabel(device);
403void QStorageInfoPrivate::retrieveVolumeInfo()
407 QT_EINTR_LOOP(result,
QT_STATFS(QFile::encodeName(rootPath).constData(), &statfs_buf));
408 valid = ready = (result == 0);
410#if defined(Q_OS_INTEGRITY) || (defined(Q_OS_BSD4) && !defined(Q_OS_NETBSD)) || defined(Q_OS_RTEMS)
411 bytesTotal = statfs_buf.f_blocks * statfs_buf.f_bsize;
412 bytesFree = statfs_buf.f_bfree * statfs_buf.f_bsize;
413 bytesAvailable = statfs_buf.f_bavail * statfs_buf.f_bsize;
415 bytesTotal = statfs_buf.f_blocks * statfs_buf.f_frsize;
416 bytesFree = statfs_buf.f_bfree * statfs_buf.f_frsize;
417 bytesAvailable = statfs_buf.f_bavail * statfs_buf.f_frsize;
419 blockSize =
int(statfs_buf.f_bsize);
420#if defined(Q_OS_ANDROID) || defined(Q_OS_BSD4) || defined(Q_OS_INTEGRITY) || defined(Q_OS_RTEMS)
421#if defined(_STATFS_F_FLAGS)
422 readOnly = (statfs_buf.f_flags & ST_RDONLY) != 0;
425 readOnly = (statfs_buf.f_flag &
ST_RDONLY) != 0;
430void QStorageInfoPrivate::initRootPath()
432 rootPath = QFileInfo(rootPath).canonicalFilePath();
434 if (rootPath.isEmpty())
439 rootPath = QStringLiteral(
"/");
444 const QString oldRootPath = rootPath;
448 const QString mountDir = it.rootPath();
449 const QByteArray fsName = it.fileSystemType();
451 if (maxLength < mountDir.size() && isParentOf(mountDir, oldRootPath)) {
452 maxLength = mountDir.size();
454 device = it.device();
455 fileSystemType = fsName;
456 subvolume = it.subvolume();
461QList<QStorageInfo> QStorageInfoPrivate::mountedVolumes()
465 return QList<QStorageInfo>() << root();
467 QList<QStorageInfo> volumes;
470 if (!shouldIncludeFs(it.rootPath(), it.fileSystemType()))
473 const QString mountDir = it.rootPath();
474 QStorageInfo info(mountDir);
475 info.d->device = it.device();
476 info.d->fileSystemType = it.fileSystemType();
477 info.d->subvolume = it.subvolume();
478 if (info.bytesTotal() <= 0 && info != root())
480 volumes.append(info);
QByteArray device() const
QByteArray subvolume() const
QByteArray options() const
QByteArray fileSystemType() const
static QString retrieveLabel(const QByteArray &device)