From 54f129f765e8418ad47178f24fef5935c9d18947 Mon Sep 17 00:00:00 2001 From: pmx <4627108+pmxy@users.noreply.github.com> Date: Wed, 12 Nov 2025 23:25:31 +0100 Subject: [PATCH] FIX SDL_GetJoystickSerial() always returning NULL on Linux (UDEV) (#14454) --- src/core/linux/SDL_udev.c | 37 ++++++++++++++++++++++++++++ src/core/linux/SDL_udev.h | 1 + src/joystick/linux/SDL_sysjoystick.c | 7 ++++++ 3 files changed, 45 insertions(+) diff --git a/src/core/linux/SDL_udev.c b/src/core/linux/SDL_udev.c index 2903ec34b4..1a2ba4df81 100644 --- a/src/core/linux/SDL_udev.c +++ b/src/core/linux/SDL_udev.c @@ -302,6 +302,43 @@ bool SDL_UDEV_GetProductInfo(const char *device_path, struct input_id *inpid, in return true; } +bool SDL_UDEV_GetProductSerial(const char *device_path, const char **serial) +{ + struct stat statbuf; + char type; + struct udev_device *dev; + const char *val; + + if (!_this) { + return false; + } + + if (stat(device_path, &statbuf) < 0) { + return false; + } + + if (S_ISBLK(statbuf.st_mode)) { + type = 'b'; + } else if (S_ISCHR(statbuf.st_mode)) { + type = 'c'; + } else { + return false; + } + + dev = _this->syms.udev_device_new_from_devnum(_this->udev, type, statbuf.st_rdev); + if (!dev) { + return false; + } + + val = _this->syms.udev_device_get_property_value(dev, "ID_SERIAL_SHORT"); + if (val) { + *serial = val; + return true; + } + + return false; +} + void SDL_UDEV_UnloadLibrary(void) { if (!_this) { diff --git a/src/core/linux/SDL_udev.h b/src/core/linux/SDL_udev.h index e99d06a5be..fbe4220776 100644 --- a/src/core/linux/SDL_udev.h +++ b/src/core/linux/SDL_udev.h @@ -105,6 +105,7 @@ extern bool SDL_UDEV_LoadLibrary(void); extern void SDL_UDEV_Poll(void); extern bool SDL_UDEV_Scan(void); extern bool SDL_UDEV_GetProductInfo(const char *device_path, struct input_id *inpid, int *class, char **driver); +extern bool SDL_UDEV_GetProductSerial(const char *device_path, const char **serial); extern bool SDL_UDEV_AddCallback(SDL_UDEV_Callback cb); extern void SDL_UDEV_DelCallback(SDL_UDEV_Callback cb); extern const SDL_UDEV_Symbols *SDL_UDEV_GetUdevSyms(void); diff --git a/src/joystick/linux/SDL_sysjoystick.c b/src/joystick/linux/SDL_sysjoystick.c index d4bb979081..c94658f6e0 100644 --- a/src/joystick/linux/SDL_sysjoystick.c +++ b/src/joystick/linux/SDL_sysjoystick.c @@ -1608,6 +1608,13 @@ static bool LINUX_JoystickOpen(SDL_Joystick *joystick, int device_index) item_sensor->hwdata = joystick->hwdata; } +#ifdef SDL_USE_LIBUDEV + const char *serial = NULL; + if (SDL_UDEV_GetProductSerial(item->path, &serial)) { + joystick->serial = SDL_strdup(serial); + } +#endif + // mark joystick as fresh and ready joystick->hwdata->fresh = true;