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

Peter Hutterer peter.hutterer at who-t.net
Sun Jan 19 13:39:04 PST 2014


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? 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


More information about the Input-tools mailing list