• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2013 Red Hat, Inc.
4  */
5 
6 #include "config.h"
7 #include <dirent.h>
8 #include <errno.h>
9 #include <fcntl.h>
10 #include <linux/uinput.h>
11 #include <poll.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include <sys/stat.h>
15 #include <time.h>
16 #include <unistd.h>
17 
18 #include "libevdev-int.h"
19 #include "libevdev-uinput-int.h"
20 #include "libevdev-uinput.h"
21 #include "libevdev-util.h"
22 #include "libevdev.h"
23 
24 #ifndef UINPUT_IOCTL_BASE
25 #define UINPUT_IOCTL_BASE       'U'
26 #endif
27 
28 #ifndef UI_SET_PROPBIT
29 #define UI_SET_PROPBIT _IOW(UINPUT_IOCTL_BASE, 110, int)
30 #endif
31 
32 static struct libevdev_uinput *
alloc_uinput_device(const char * name)33 alloc_uinput_device(const char *name)
34 {
35 	struct libevdev_uinput *uinput_dev;
36 
37 	uinput_dev = calloc(1, sizeof(struct libevdev_uinput));
38 	if (uinput_dev) {
39 		uinput_dev->name = strdup(name);
40 		uinput_dev->fd = -1;
41 	}
42 
43 	return uinput_dev;
44 }
45 
46 static inline int
set_abs(const struct libevdev * dev,int fd,unsigned int code)47 set_abs(const struct libevdev *dev, int fd, unsigned int code)
48 {
49 	const struct input_absinfo *abs = libevdev_get_abs_info(dev, code);
50 	struct uinput_abs_setup abs_setup = {0};
51 	int rc;
52 
53 	abs_setup.code = code;
54 	abs_setup.absinfo = *abs;
55 	rc = ioctl(fd, UI_ABS_SETUP, &abs_setup);
56 	return rc;
57 }
58 
59 static int
set_evbits(const struct libevdev * dev,int fd,struct uinput_user_dev * uidev)60 set_evbits(const struct libevdev *dev, int fd, struct uinput_user_dev *uidev)
61 {
62 	int rc = 0;
63 	unsigned int type;
64 
65 	for (type = 0; type < EV_CNT; type++) {
66 		unsigned int code;
67 		int max;
68 		int uinput_bit;
69 		const unsigned long *mask;
70 
71 		if (!libevdev_has_event_type(dev, type))
72 			continue;
73 
74 		rc = ioctl(fd, UI_SET_EVBIT, type);
75 		if (rc == -1)
76 			break;
77 
78 		/* uinput can't set EV_REP */
79 		if (type == EV_REP)
80 			continue;
81 
82 		max = type_to_mask_const(dev, type, &mask);
83 		if (max == -1)
84 			continue;
85 
86 		switch(type) {
87 			case EV_KEY: uinput_bit = UI_SET_KEYBIT; break;
88 			case EV_REL: uinput_bit = UI_SET_RELBIT; break;
89 			case EV_ABS: uinput_bit = UI_SET_ABSBIT; break;
90 			case EV_MSC: uinput_bit = UI_SET_MSCBIT; break;
91 			case EV_LED: uinput_bit = UI_SET_LEDBIT; break;
92 			case EV_SND: uinput_bit = UI_SET_SNDBIT; break;
93 			case EV_FF: uinput_bit = UI_SET_FFBIT; break;
94 			case EV_SW: uinput_bit = UI_SET_SWBIT; break;
95 			default:
96 				    rc = -1;
97 				    errno = EINVAL;
98 				    goto out;
99 		}
100 
101 		for (code = 0; code <= (unsigned int)max; code++) {
102 			if (!libevdev_has_event_code(dev, type, code))
103 				continue;
104 
105 			rc = ioctl(fd, uinput_bit, code);
106 			if (rc == -1)
107 				goto out;
108 
109 			if (type == EV_ABS) {
110 				if (uidev == NULL) {
111 					rc = set_abs(dev, fd, code);
112 					if (rc != 0)
113 						goto out;
114 				} else {
115 					const struct input_absinfo *abs =
116 						libevdev_get_abs_info(dev, code);
117 
118 					uidev->absmin[code] = abs->minimum;
119 					uidev->absmax[code] = abs->maximum;
120 					uidev->absfuzz[code] = abs->fuzz;
121 					uidev->absflat[code] = abs->flat;
122 					/* uinput has no resolution in the
123 					 * device struct */
124 				}
125 			}
126 		}
127 
128 	}
129 
130 out:
131 	return rc;
132 }
133 
134 static int
set_props(const struct libevdev * dev,int fd)135 set_props(const struct libevdev *dev, int fd)
136 {
137 	unsigned int prop;
138 	int rc = 0;
139 
140 	for (prop = 0; prop <= INPUT_PROP_MAX; prop++) {
141 		if (!libevdev_has_property(dev, prop))
142 			continue;
143 
144 		rc = ioctl(fd, UI_SET_PROPBIT, prop);
145 		if (rc == -1) {
146 			/* If UI_SET_PROPBIT is not supported, treat -EINVAL
147 			 * as success. The kernel only sends -EINVAL for an
148 			 * invalid ioctl, invalid INPUT_PROP_MAX or if the
149 			 * ioctl is called on an already created device. The
150 			 * last two can't happen here.
151 			 */
152 			if (errno == EINVAL)
153 				rc = 0;
154 			break;
155 		}
156 	}
157 	return rc;
158 }
159 
160 LIBEVDEV_EXPORT int
libevdev_uinput_get_fd(const struct libevdev_uinput * uinput_dev)161 libevdev_uinput_get_fd(const struct libevdev_uinput *uinput_dev)
162 {
163 	return uinput_dev->fd;
164 }
165 
166 #ifdef __FreeBSD__
167 /*
168  * FreeBSD does not have anything similar to sysfs.
169  * Set libevdev_uinput->syspath to NULL unconditionally.
170  * Look up the device nodes directly instead of via sysfs, as this matches what
171  * is returned by the UI_GET_SYSNAME ioctl() on FreeBSD.
172  */
173 static int
fetch_syspath_and_devnode(struct libevdev_uinput * uinput_dev)174 fetch_syspath_and_devnode(struct libevdev_uinput *uinput_dev)
175 {
176 #define DEV_INPUT_DIR "/dev/input/"
177 	int rc;
178 	char buf[sizeof(DEV_INPUT_DIR) + 64] = DEV_INPUT_DIR;
179 
180 	rc = ioctl(uinput_dev->fd,
181 	           UI_GET_SYSNAME(sizeof(buf) - strlen(DEV_INPUT_DIR)),
182 		   &buf[strlen(DEV_INPUT_DIR)]);
183 	if (rc == -1)
184 		return -1;
185 
186 	uinput_dev->syspath = NULL;
187 	uinput_dev->devnode = strdup(buf);
188 
189 	return 0;
190 #undef DEV_INPUT_DIR
191 }
192 
193 #else /* !__FreeBSD__ */
194 
is_event_device(const struct dirent * dent)195 static int is_event_device(const struct dirent *dent) {
196 	return strncmp("event", dent->d_name, 5) == 0;
197 }
198 
199 static char *
fetch_device_node(const char * path)200 fetch_device_node(const char *path)
201 {
202 	char *devnode = NULL;
203 	struct dirent **namelist;
204 	int ndev, i;
205 
206 	ndev = scandir(path, &namelist, is_event_device, alphasort);
207 	if (ndev <= 0)
208 		return NULL;
209 
210 	/* ndev should only ever be 1 */
211 
212 	for (i = 0; i < ndev; i++) {
213 		if (!devnode && asprintf(&devnode, "/dev/input/%s", namelist[i]->d_name) == -1)
214 			devnode = NULL;
215 		free(namelist[i]);
216 	}
217 
218 	free(namelist);
219 
220 	return devnode;
221 }
222 
is_input_device(const struct dirent * dent)223 static int is_input_device(const struct dirent *dent) {
224 	return strncmp("input", dent->d_name, 5) == 0;
225 }
226 
227 static int
fetch_syspath_and_devnode(struct libevdev_uinput * uinput_dev)228 fetch_syspath_and_devnode(struct libevdev_uinput *uinput_dev)
229 {
230 #define SYS_INPUT_DIR "/sys/devices/virtual/input/"
231 	struct dirent **namelist;
232 	int ndev, i;
233 	int rc;
234 	char buf[sizeof(SYS_INPUT_DIR) + 64] = SYS_INPUT_DIR;
235 
236 	rc = ioctl(uinput_dev->fd,
237 		   UI_GET_SYSNAME(sizeof(buf) - strlen(SYS_INPUT_DIR)),
238 		   &buf[strlen(SYS_INPUT_DIR)]);
239 	if (rc != -1) {
240 		uinput_dev->syspath = strdup(buf);
241 		uinput_dev->devnode = fetch_device_node(buf);
242 		return 0;
243 	}
244 
245 	ndev = scandir(SYS_INPUT_DIR, &namelist, is_input_device, alphasort);
246 	if (ndev <= 0)
247 		return -1;
248 
249 	for (i = 0; i < ndev; i++) {
250 		int fd, len;
251 		struct stat st;
252 
253 		rc = snprintf(buf, sizeof(buf), "%s%s/name",
254 			      SYS_INPUT_DIR,
255 			      namelist[i]->d_name);
256 		if (rc < 0 || (size_t)rc >= sizeof(buf)) {
257 			continue;
258 		}
259 
260 		/* created within time frame */
261 		fd = open(buf, O_RDONLY);
262 		if (fd < 0)
263 			continue;
264 
265 		/* created before UI_DEV_CREATE, or after it finished */
266 		if (fstat(fd, &st) == -1 ||
267 		    st.st_ctime < uinput_dev->ctime[0] ||
268 		    st.st_ctime > uinput_dev->ctime[1]) {
269 			close(fd);
270 			continue;
271 		}
272 
273 		len = read(fd, buf, sizeof(buf));
274 		close(fd);
275 		if (len <= 0)
276 			continue;
277 
278 		buf[len - 1] = '\0'; /* file contains \n */
279 		if (strcmp(buf, uinput_dev->name) == 0) {
280 			if (uinput_dev->syspath) {
281 				/* FIXME: could descend into bit comparison here */
282 				log_info(NULL, "multiple identical devices found. syspath is unreliable\n");
283 				break;
284 			}
285 
286 			rc = snprintf(buf, sizeof(buf), "%s%s",
287 				      SYS_INPUT_DIR,
288 				      namelist[i]->d_name);
289 
290 			if (rc < 0 || (size_t)rc >= sizeof(buf)) {
291 				log_error(NULL, "Invalid syspath, syspath is unreliable\n");
292 				break;
293 			}
294 
295 			uinput_dev->syspath = strdup(buf);
296 			uinput_dev->devnode = fetch_device_node(buf);
297 		}
298 	}
299 
300 	for (i = 0; i < ndev; i++)
301 		free(namelist[i]);
302 	free(namelist);
303 
304 	return uinput_dev->devnode ? 0 : -1;
305 #undef SYS_INPUT_DIR
306 }
307 #endif /* __FreeBSD__*/
308 
309 static int
uinput_create_write(const struct libevdev * dev,int fd)310 uinput_create_write(const struct libevdev *dev, int fd)
311 {
312 	int rc;
313 	struct uinput_user_dev uidev;
314 
315 	memset(&uidev, 0, sizeof(uidev));
316 
317 	strncpy(uidev.name, libevdev_get_name(dev), UINPUT_MAX_NAME_SIZE - 1);
318 	uidev.id.vendor = libevdev_get_id_vendor(dev);
319 	uidev.id.product = libevdev_get_id_product(dev);
320 	uidev.id.bustype = libevdev_get_id_bustype(dev);
321 	uidev.id.version = libevdev_get_id_version(dev);
322 
323 	if (set_evbits(dev, fd, &uidev) != 0)
324 		goto error;
325 	if (set_props(dev, fd) != 0)
326 		goto error;
327 
328 	rc = write(fd, &uidev, sizeof(uidev));
329 	if (rc < 0) {
330 		goto error;
331 	} else if ((size_t)rc < sizeof(uidev)) {
332 		errno = EINVAL;
333 		goto error;
334 	}
335 
336 	errno = 0;
337 
338 error:
339 	return -errno;
340 }
341 
342 static int
uinput_create_DEV_SETUP(const struct libevdev * dev,int fd,struct libevdev_uinput * new_device)343 uinput_create_DEV_SETUP(const struct libevdev *dev, int fd,
344 			struct libevdev_uinput *new_device)
345 {
346 	int rc;
347 	struct uinput_setup setup;
348 
349 	if (set_evbits(dev, fd, NULL) != 0)
350 		goto error;
351 	if (set_props(dev, fd) != 0)
352 		goto error;
353 
354 	memset(&setup, 0, sizeof(setup));
355 	strncpy(setup.name, libevdev_get_name(dev), UINPUT_MAX_NAME_SIZE - 1);
356 	setup.id.vendor = libevdev_get_id_vendor(dev);
357 	setup.id.product = libevdev_get_id_product(dev);
358 	setup.id.bustype = libevdev_get_id_bustype(dev);
359 	setup.id.version = libevdev_get_id_version(dev);
360 	setup.ff_effects_max = libevdev_has_event_type(dev, EV_FF) ? 10 : 0;
361 
362 	rc = ioctl(fd, UI_DEV_SETUP, &setup);
363 	if (rc == 0)
364 		errno = 0;
365 error:
366 	return -errno;
367 }
368 
369 LIBEVDEV_EXPORT int
libevdev_uinput_create_from_device(const struct libevdev * dev,int fd,struct libevdev_uinput ** uinput_dev)370 libevdev_uinput_create_from_device(const struct libevdev *dev, int fd, struct libevdev_uinput** uinput_dev)
371 {
372 	int rc;
373 	struct libevdev_uinput *new_device;
374 	int close_fd_on_error = (fd == LIBEVDEV_UINPUT_OPEN_MANAGED);
375 	unsigned int uinput_version = 0;
376 
377 	new_device = alloc_uinput_device(libevdev_get_name(dev));
378 	if (!new_device)
379 		return -ENOMEM;
380 
381 	if (fd == LIBEVDEV_UINPUT_OPEN_MANAGED) {
382 		fd = open("/dev/uinput", O_RDWR|O_CLOEXEC);
383 		if (fd < 0)
384 			goto error;
385 
386 		new_device->fd_is_managed = 1;
387 	} else if (fd < 0) {
388 		log_bug(NULL, "Invalid fd %d\n", fd);
389 		errno = EBADF;
390 		goto error;
391 	}
392 
393 	if (ioctl(fd, UI_GET_VERSION, &uinput_version) == 0 &&
394 	    uinput_version >= 5)
395 		rc = uinput_create_DEV_SETUP(dev, fd, new_device);
396 	else
397 		rc = uinput_create_write(dev, fd);
398 
399 	if (rc != 0)
400 		goto error;
401 
402 	/* ctime notes time before/after ioctl to help us filter out devices
403 	   when traversing /sys/devices/virtual/input to find the device
404 	   node.
405 
406 	   this is in seconds, so ctime[0]/[1] will almost always be
407 	   identical but /sys doesn't give us sub-second ctime so...
408 	 */
409 	new_device->ctime[0] = time(NULL);
410 
411 	rc = ioctl(fd, UI_DEV_CREATE, NULL);
412 	if (rc == -1)
413 		goto error;
414 
415 	new_device->ctime[1] = time(NULL);
416 	new_device->fd = fd;
417 
418 	if (fetch_syspath_and_devnode(new_device) == -1) {
419 		log_error(NULL, "unable to fetch syspath or device node.\n");
420 		errno = ENODEV;
421 		goto error;
422 	}
423 
424 	*uinput_dev = new_device;
425 
426 	return 0;
427 
428 error:
429 	rc = -errno;
430 	libevdev_uinput_destroy(new_device);
431 	if (fd != -1 && close_fd_on_error)
432 		close(fd);
433 	return rc;
434 }
435 
436 LIBEVDEV_EXPORT void
libevdev_uinput_destroy(struct libevdev_uinput * uinput_dev)437 libevdev_uinput_destroy(struct libevdev_uinput *uinput_dev)
438 {
439 	if (!uinput_dev)
440 		return;
441 
442 	if (uinput_dev->fd >= 0) {
443 		(void)ioctl(uinput_dev->fd, UI_DEV_DESTROY, NULL);
444 		if (uinput_dev->fd_is_managed)
445 			close(uinput_dev->fd);
446 	}
447 	free(uinput_dev->syspath);
448 	free(uinput_dev->devnode);
449 	free(uinput_dev->name);
450 	free(uinput_dev);
451 }
452 
453 LIBEVDEV_EXPORT const char*
libevdev_uinput_get_syspath(struct libevdev_uinput * uinput_dev)454 libevdev_uinput_get_syspath(struct libevdev_uinput *uinput_dev)
455 {
456 	return uinput_dev->syspath;
457 }
458 
459 LIBEVDEV_EXPORT const char*
libevdev_uinput_get_devnode(struct libevdev_uinput * uinput_dev)460 libevdev_uinput_get_devnode(struct libevdev_uinput *uinput_dev)
461 {
462 	return uinput_dev->devnode;
463 }
464 
465 LIBEVDEV_EXPORT int
libevdev_uinput_write_event(const struct libevdev_uinput * uinput_dev,unsigned int type,unsigned int code,int value)466 libevdev_uinput_write_event(const struct libevdev_uinput *uinput_dev,
467 			    unsigned int type,
468 			    unsigned int code,
469 			    int value)
470 {
471 	struct input_event ev = {type, code, value};
472 	int fd = libevdev_uinput_get_fd(uinput_dev);
473 	int rc, max;
474 
475 	if (type > EV_MAX)
476 		return -EINVAL;
477 
478 	max = libevdev_event_type_get_max(type);
479 	if (max == -1 || code > (unsigned int)max)
480 		return -EINVAL;
481 
482 	rc = write(fd, &ev, sizeof(ev));
483 
484 	return rc < 0 ? -errno : 0;
485 }
486