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 <justin@jgottula.com>
This commit is contained in:
Justin Gottula
2018-12-24 10:04:04 -08:00
committed by Jente Hidskes
parent 635865efa5
commit 44d36d2bf0

View File

@@ -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));