This is a quick note about how to search device nodes in Qt.
TLDR
Add QDir::System
explicitly in the filter of a QDir
object to include device nodes.
Long story
The QDir
class provides access to directory structures and their contents. When constructing a QDir
object, there are three elements can be used to control which directory and contents that can be accessed:
- path: in which directory you are going to access, e.g.
/dev
. - name filter: to filter the contents by name, e.g.
*.cpp
,sdb?
. It understands*
and?
wildcards, but not full regular expression. Both path and name filters are a type ofQString
. - filter: Any combination of variants of
QDir::Filters
enumeration.
Note: Another element “sort flags” (QDir::SortFlags
) is used to specify how to sort the items in the list, however, it doesn’t affect if any files are included or not.
If you want to iterate through all the partition device nodes of /dev/sdb
like this:
QDir devDir(QStringLiteral("/dev"), "sdb?");
for (const QFileInfo &blockInfo : devDir.entryInfoList())
if (blockInfo.exists())
qDebug() << blockInfo.fileName();
It doesn’t work. Here’s the reason.
The default filter is QDir::Filters( Dirs|Files|Drives|AllEntries )
, and QDir::AllEntries
is defined as QDir::Filters( Dirs|Files|Drives )
, so the default filter is actually only QDir::Filters( Dirs|Files|Drives )
. And in order to list device files (and FIFOs and sockets) on Unix, QDir::System
needs to be included in the filter. The so-called AllEntries
isn’t quite approriately named.
We can use QDir::setFilter() to add QDir::System
filter before the loop:
QDir devDir(QStringLiteral("/dev"), "sdb?");
// Add QDir::System filter to include device nodes
devDir.setFilter(devDir.filter() | QDir::System);
for (const QFileInfo &blockInfo : devDir.entryInfoList())
if (blockInfo.exists())
qDebug() << blockInfo.fileName();
Summary
The default filter of QDir
object doesn’t include QDir::System
. One has to add it explicitly to include device nodes.
Enjoy it!