keyboard_state: close fd when openDevice throws to fix fd leak

openDevice() throws without closing the fd if libevdev_new_from_fd fails.
In both update() and tryAddDevice() the outer catch only logged, so
closeFile(fd) was never reached and a descriptor leaked on every failing
tick. Guard openDevice with a try/catch that closes the fd before rethrowing.
This commit is contained in:
Alex
2026-07-05 10:13:24 +02:00
parent 8441d5e124
commit 91ca603b04
+16 -2
View File
@@ -320,7 +320,14 @@ auto waybar::modules::KeyboardState::update() -> void {
for (const auto& dev_path : dev_paths) {
try {
int fd = openFile(dev_path, O_NONBLOCK | O_CLOEXEC | O_RDONLY);
auto dev = openDevice(fd);
libevdev* dev;
try {
dev = openDevice(fd);
} catch (...) {
// openDevice does not close the fd if libevdev_new_from_fd fails.
closeFile(fd);
throw;
}
numl |= libevdev_get_event_value(dev, EV_LED, LED_NUML);
capsl |= libevdev_get_event_value(dev, EV_LED, LED_CAPSL);
scrolll |= libevdev_get_event_value(dev, EV_LED, LED_SCROLLL);
@@ -376,7 +383,14 @@ auto waybar::modules::KeyboardState::update() -> void {
auto waybar::modules ::KeyboardState::tryAddDevice(const std::string& dev_path) -> void {
try {
int fd = openFile(dev_path, O_NONBLOCK | O_CLOEXEC | O_RDONLY);
auto dev = openDevice(fd);
libevdev* dev;
try {
dev = openDevice(fd);
} catch (...) {
// openDevice does not close the fd if libevdev_new_from_fd fails.
closeFile(fd);
throw;
}
if (supportsLockStates(dev)) {
spdlog::info("Found device {} at '{}'", libevdev_get_name(dev), dev_path);
std::lock_guard<std::mutex> lock(devices_mutex_);