/* See LICENSE file for copyright and license details. */ #include "common.h" int libgamepad_get_attachment_event(LIBGAMEPAD_ATTACHMENT_MONITOR *monitor, char **syspathp, size_t *sizep, enum libgamepad_attachment_event_type *typep) { struct udev_device *device; const char *action; const char *syspath; size_t len; void *new; char *syspath_end; int saved_errno; device = udev_monitor_receive_device(monitor->monitor); if (!device) return -1; action = udev_device_get_action(device); if (!strcmp(action, "bind")) *typep = LIBGAMEPAD_ADDED; else if (!strcmp(action, "unbind")) *typep = LIBGAMEPAD_REMOVED; else goto suppress; syspath = udev_device_get_syspath(device); if (!syspath || !*syspath) goto suppress; len = strlen(syspath) + sizeof("/hidraw"); if (len > *sizep) { new = realloc(*syspathp, len); if (!new) { udev_device_unref(device); return -1; } *syspathp = new; *sizep = len; } syspath_end = stpcpy(*syspathp, syspath); if (*typep == LIBGAMEPAD_ADDED) { stpcpy(syspath_end, "/hidraw"); saved_errno = errno; if (access(*syspathp, F_OK)) { errno = saved_errno; goto suppress; } *syspath_end = '\0'; } udev_device_unref(device); return 1; suppress: udev_device_unref(device); return 0; }