[PATCH libevdev] uinput: Add ioctl to get the sysname of the created input device

David Herrmann dh.herrmann at gmail.com
Sun Jan 19 14:23:55 PST 2014


Hi Peter

On Sun, Jan 19, 2014 at 10:39 PM, Peter Hutterer
<peter.hutterer at who-t.net> wrote:
> On Fri, Jan 17, 2014 at 02:08:00PM -0500, Benjamin Tissoires wrote:
>> From: Benjamin Tisssoires <benjamin.tissoires at gmail.com>
>>
>> The kernel shipping uinput version >= 4 can give us the sysname of the created
>> input device. This allows to retrieve for sure the name of the input node in /dev/input/,
>> whereas the current implementation relies on a heuristic which may fail if two
>> uinput device are created at the same time.
>>
>> If the kernel supports the ioctl, it will return a different code than -EINVAL, so
>> if it does not support this new ioctl, rely on our old heuristic.
>>
>> Signed-off-by: Benjamin Tisssoires <benjamin.tissoires at gmail.com>
>> ---
>>
>> Hi guys,
>>
>> I am posting this patch here while I am submitting the kernel part. So, as long
>> as the kernel part is not taken, this one stays as an RFC and consider this for
>> history records.
>>
>> Of course, reviews are still welcome :)
>>
>> Cheers,
>> Benjamin
>>
>>  libevdev/libevdev-uinput-int.h |  3 +++
>>  libevdev/libevdev-uinput.c     | 46 ++++++++++++++++++++++++++++++++++++++----
>>  2 files changed, 45 insertions(+), 4 deletions(-)
>>
>> diff --git a/libevdev/libevdev-uinput-int.h b/libevdev/libevdev-uinput-int.h
>> index fbc1c29..ab50fa1 100644
>> --- a/libevdev/libevdev-uinput-int.h
>> +++ b/libevdev/libevdev-uinput-int.h
>> @@ -20,6 +20,9 @@
>>   * OF THIS SOFTWARE.
>>   */
>>
>> +#ifndef UI_GET_SYSNAME
>> +#define UI_GET_SYSNAME(len)  _IOC(_IOC_READ, UINPUT_IOCTL_BASE, 300, len)
>> +#endif
>>
>>  struct libevdev_uinput {
>>       int fd; /**< file descriptor to uinput */
>> diff --git a/libevdev/libevdev-uinput.c b/libevdev/libevdev-uinput.c
>> index ea9cf78..409fcce 100644
>> --- a/libevdev/libevdev-uinput.c
>> +++ b/libevdev/libevdev-uinput.c
>> @@ -203,13 +203,34 @@ static int is_input_device(const struct dirent *dent) {
>>  }
>>
>>  static int
>> -fetch_syspath_and_devnode(struct libevdev_uinput *uinput_dev)
>> +fetch_syspath_from_ioctl(struct libevdev_uinput *uinput_dev)
>> +{
>> +     int ret;
>> +     char name[64];
>> +     char path[sizeof(SYS_INPUT_DIR) + sizeof(name)] = SYS_INPUT_DIR;
>> +
>> +     ret = ioctl(uinput_dev->fd, UI_GET_SYSNAME(sizeof(name)), name);
>> +     if (ret < 0)
>> +             return ret;
>
> this should be return -errno, right? just for consistency, even though we
> don't use it in the caller.
>
>> +
>> +     if (ret == sizeof(name)) {
>> +             log_bug("error: incomplete sysfs name: \"%s\" (len %d)\n", name, ret - 1);
>
> the kernel doesn't null-terminate if the buffer is too small, right?

It does.

Thanks
David

> If so,
> you need a name[sizeof(name)-1] = '\0' before this.
>
> otherwise:
> Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>, once we have this in
> the kernel I'm happy to merge it.
>
> Cheers,
>    Peter
>
>
>> +             return -ENAMETOOLONG;
>> +     }
>> +
>> +     strcat(path, name);
>> +
>> +     uinput_dev->syspath = strdup(path);
>> +
>> +     return 0;
>> +}
>> +
>> +static int
>> +fetch_syspath_from_heuristic(struct libevdev_uinput *uinput_dev)
>>  {
>>       struct dirent **namelist;
>>       int ndev, i;
>>
>> -     /* FIXME: use new ioctl() here once kernel supports it */
>> -
>>       ndev = scandir(SYS_INPUT_DIR, &namelist, is_input_device, alphasort);
>>       if (ndev <= 0)
>>               return -1;
>> @@ -251,7 +272,6 @@ fetch_syspath_and_devnode(struct libevdev_uinput *uinput_dev)
>>                               strcpy(buf, SYS_INPUT_DIR);
>>                               strcat(buf, namelist[i]->d_name);
>>                               uinput_dev->syspath = strdup(buf);
>> -                             uinput_dev->devnode = fetch_device_node(buf);
>>                       }
>>               }
>>       }
>> @@ -260,6 +280,24 @@ fetch_syspath_and_devnode(struct libevdev_uinput *uinput_dev)
>>               free(namelist[i]);
>>       free(namelist);
>>
>> +     return uinput_dev->syspath ? 0 : -1;
>> +}
>> +
>> +static int
>> +fetch_syspath_and_devnode(struct libevdev_uinput *uinput_dev)
>> +{
>> +     int ret;
>> +
>> +     ret = fetch_syspath_from_ioctl(uinput_dev);
>> +     if (ret == -EINVAL)
>> +             /* ioctl not available with the current kernel, try the old method */
>> +             ret = fetch_syspath_from_heuristic(uinput_dev);
>> +
>> +     if (ret)
>> +             return -1;
>> +
>> +     uinput_dev->devnode = fetch_device_node(uinput_dev->syspath);
>> +
>>       return uinput_dev->devnode ? 0 : -1;
>>  }
>>
>> --
>> 1.8.3.1
>>
>> _______________________________________________
>> Input-tools mailing list
>> Input-tools at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/input-tools
> _______________________________________________
> Input-tools mailing list
> Input-tools at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/input-tools


More information about the Input-tools mailing list