> ## Content Index
> Fetch the complete content index at: https://www.smallstepsystems.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Monitoring Sys Files with QFileSystemWatcher
- URL: https://www.smallstepsystems.com/monitoring-sys-files-qfilesystemwatcher/
- Published: 2018-09-18T18:29:23.000Z
- Updated: 2026-01-25T15:47:41.000Z
- Author: Burkhard Stubert

When the driver turns off the ignition in a vehicle, display computers like terminals in harvesters or infotainment systems in cars should be notified. The display computers should save important data and shut down orderly.

When the display computer runs on Linux, it learns the status of the ignition by monitoring the GPIO for clamp 15\. Linux writes the value of the GPIO to a special file in the *sys filesystem*. On one of my display computers, clamp15 is mapped to the special file `/sys/class/gpio/gpio72/value`. When the ignition is on, this file contains the string "1". When off, this file contains "0". The number of GPIO (here: 72) varies from display computer to display computer.

On the Linux command line, we get the value of clamp 15 with this command:

$ cat /sys/class/gpio/gpio72/value 1

The command returns "0" when the ignition is off and "1" when it is on.

How can a Qt application monitor the status of the GPIO clamp 15 such that it can shut down orderly when the driver turns off the ignition?

Our first idea most likely is to use [QFileSystemWatcher](https://doc.qt.io/qt-5/qfilesystemwatcher.html?ref=smallstepsystems.com) on the file `/sys/class/gpio/gpio72/value`. `QFileSystemWatcher` does exactly what we want. When the watched file is modified, `QFileSystemWatcher` emits the signal `fileChanged(const QString &path)`. We connect a slot to this signal and read the value from the sys file.

// In the constructor of SomeClass auto clamp15Monitor = new QFileSystemWatcher{this}; clamp15Monitor->addPath("/sys/class/gpio/gpio72/value"); connect(clamp15Monitor, &QFileSystemWatcher::fileChanged, this, &HarvesterServicesImpl::onClamp15FileChanged);

The slot `onClamp15FileChanged` does nothing else but the command `cat /sys/class/gpio/gpio72/value`. It reads the value from the sys file and prints it.

void SomeClass::onClamp15FileChanged(const QString &path) { QFile clamp15File{filePath}; if (!clamp15File.open(QIODevice::ReadOnly)) { qWarning() << "ERROR: Could not open clamp15 file."; return; } auto clamp15 = clamp15File.readAll(); if (!clamp15.isEmpty()) { qDebug() << "INFO: clamp15 = " << clamp15.at(0); } }

When we run this code, we are flooded with *INFO* messages. The messages show the correct value of clamp 15 - many times per second. However, we want to see an *INFO* message only when the value of clamp 15 changes.

We could give up at this point and set up a `QTimer`, which calls `onClamp15FileChanged()` every second. We poll the status of the clamp-15 file once a second. This works, but it wastes many CPU cycles.

Fortunately, we can do better. The file `/sys/class/gpio/gpio72/edge` comes to our rescue. Section "GPIO and sysfs" (p. 394ff) of [John Madieu's book "Linux Device Drivers Development"](https://www.amazon.com/Linux-Device-Drivers-Development-customized/dp/1785280007/ref=sr%5F1%5F1?s=books&ie=UTF8&qid=1532259921&sr=1-1&ref=smallstepsystems.com) points us in the right direction.

> `edgepollselectnonerisingfallingboth`

The system functions `poll` and `select` monitor I/O activities on file descriptors. John Madieu explains:

> `poll (2)/sys/class/gpio/gpio72/valuepoll (2)poll (2)POLLPRIselect (2)exceptfdspoll (2)lseek (2)`

In other words: If the Linux kernel (the GPIO device driver, to be exact) sees an edge on a GPIO, it triggers an interrupt. The interrupt writes the changed value into the sysfs file corresponding to the GPIO. `poll` and `select` see this activity on the monitored file descriptor and return from blocking. The caller of these system functions can read the contents of the sys file.

As `QFileSystemWatcher` is implemented with one of these system functions, we should get it working properly. The trick is to configure the GPIO device driver to check for edges on GPIO 72\. This isn't the case, as the command

$ cat /sys/class/gpio/gpio72/edge none

shows. This explains why `QFileSystemWatcher` has been misbehaving so far. We configure GPIO 72 to check for "both" edges with the following command:

$ echo "both" > /sys/class/gpio/gpio72/edge

When we run our application now, we will see *INFO* messages only when the value of `/sys/class/gpio/gpio72/value` changes. We never see the same value twice in a row. `QFileSystemWatcher` emits its signal `fileChanged` only if the driver turns the ignition from "on" to "off" or from "off" to "on".