From 91ca603b04cdb95a330ae054f049dc32578ab325 Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 5 Jul 2026 10:10:10 +0200 Subject: [PATCH] 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. --- src/modules/keyboard_state.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/modules/keyboard_state.cpp b/src/modules/keyboard_state.cpp index 87a843c4..fa80ef64 100644 --- a/src/modules/keyboard_state.cpp +++ b/src/modules/keyboard_state.cpp @@ -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 lock(devices_mutex_);