From 44d36d2bf0549081386c561d1e7fed3651a737c4 Mon Sep 17 00:00:00 2001 From: Justin Gottula Date: Mon, 24 Dec 2018 10:04:04 -0800 Subject: [PATCH] tools: canonicalize path first in udev_device_from_path (#592) * tools: canonicalize path first in udev_device_from_path This fixes a problem in which running ratbag-command with the path to a device node symlink (e.g. /dev/logi-g502 -> /dev/input/event4), such as one created by a udev rule, would not work correctly, due to the code failing to resolve the symlink prior to checking for the presence of the "/dev/input/event" prefix. This resulted in nonsensical error messages (shown below) and the curious inability to run ratbag-command successfully with anything but the actual raw path to the device node itself (e.g. /dev/input/event4 would work fine, but /dev/logi-g502 would not, despite both being valid ways of getting to the same device node). Error: Can't open '/dev/logi-g502': Success Error: Device '/dev/logi-g502' is not supported Note that this same problem also prevented the usage of autogenerated symlinks by udev, i.e. '/dev/input/by-id/' and '/dev/input/by-path/'. * Update tools/shared.c Co-Authored-By: jgottula --- tools/shared.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tools/shared.c b/tools/shared.c index 3aff21c1..992e2de7 100644 --- a/tools/shared.c +++ b/tools/shared.c @@ -28,17 +28,22 @@ udev_device_from_path(struct udev *udev, const char *path) { struct udev_device *udev_device; const char *event_node_prefix = "/dev/input/event"; + _cleanup_(freep) char *path_canonical = NULL; - if (strneq(path, event_node_prefix, strlen(event_node_prefix))) { + if ((path_canonical = canonicalize_file_name(path)) == NULL) { + error("Failed to canonicalize path '%s': %s\n", path, strerror(errno)); + return NULL; + } + if (strneq(path_canonical, event_node_prefix, strlen(event_node_prefix))) { struct stat st; - if (stat(path, &st) == -1) { + if (stat(path_canonical, &st) == -1) { error("Failed to stat '%s': %s\n", path, strerror(errno)); return NULL; } udev_device = udev_device_new_from_devnum(udev, 'c', st.st_rdev); } else { - udev_device = udev_device_new_from_syspath(udev, path); + udev_device = udev_device_new_from_syspath(udev, path_canonical); } if (!udev_device) { error("Can't open '%s': %s\n", path, strerror(errno));