Search device nodes in Qt

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 of QString.
  • 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!

comments powered by Disqus