From 85041c12ab8e3fe162b54048349a8a977c18843d Mon Sep 17 00:00:00 2001 From: Gregory Lirent Date: Wed, 24 Jun 2026 16:50:05 +0300 Subject: [PATCH] fix(input): resolve the real evdev node for input-linux, not the sysfs name UI_GET_SYSNAME returns the input-class directory name (inputNNN), not a usable device node -- /dev/input/inputNNN does not exist, so QEMU's input-linux failed with "Could not open". Resolve the actual evdev node (/dev/input/eventN) as the event* child of /sys/class/input//. Confirmed against the live host sysfs. The unit path can't exercise this (no /dev/uinput in CI) -- armed only. Bump 0.3.10. --- CMakeLists.txt | 2 +- src/si/input/linux/uinput_driver.c | 25 +++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ee4565..49af849 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.16) # Single source of truth for the version: CI passes -DVMSIG_VERSION=${TAG#v}, so the project # version (-> libvgpu-perception SONAME/.so version) and the .deb version come from one tag. -set(VMSIG_VERSION "0.3.9" CACHE STRING "Release version (MAJOR.MINOR.PATCH); CI passes the tag") +set(VMSIG_VERSION "0.3.10" CACHE STRING "Release version (MAJOR.MINOR.PATCH); CI passes the tag") project(vmsig VERSION ${VMSIG_VERSION} LANGUAGES C) set(CMAKE_C_STANDARD 17) diff --git a/src/si/input/linux/uinput_driver.c b/src/si/input/linux/uinput_driver.c index 282957c..c27d295 100644 --- a/src/si/input/linux/uinput_driver.c +++ b/src/si/input/linux/uinput_driver.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -120,8 +121,28 @@ static int uinput_create(const uinput_role* role, const vmctl_uinput_id* id, char sysname[64] = {0}; evdev[0] = '\0'; - if (ioctl(fd, UI_GET_SYSNAME(sizeof sysname), sysname) >= 0) - snprintf(evdev, 64, "/dev/input/%s", sysname); + /* UI_GET_SYSNAME returns the input-class directory name (e.g. "input174"), NOT the usable + * device node: a bare /dev/input/ does not exist (QEMU input-linux fails to open + * it). The evdev character device is /dev/input/eventN, exposed as the "event*" child of + * /sys/class/input// — resolve it there. */ + if (ioctl(fd, UI_GET_SYSNAME(sizeof sysname), sysname) >= 0) { + char dpath[128]; + snprintf(dpath, sizeof dpath, "/sys/class/input/%s", sysname); + DIR* dir = opendir(dpath); + if (dir) { + struct dirent* de; + while ((de = readdir(dir)) != NULL) + if (strncmp(de->d_name, "event", 5) == 0) { + size_t nl = strlen(de->d_name); + if (nl + 11 < 64) { /* "/dev/input/" is 11 chars + name + NUL */ + memcpy(evdev, "/dev/input/", 11); + memcpy(evdev + 11, de->d_name, nl + 1); + } + break; + } + closedir(dir); + } + } if (!evdev[0]) { ioctl(fd, UI_DEV_DESTROY);