Как определить файлы, соответствующие устройству ввода?
В Linux, когда создается устройство ввода данных, в файловой системе создается один или несколько файлов событий, соответствующих этому устройству. (Например, если я создаю мышь uinput, то создается файл /dev/input/mouseN.) Но как определить, какие файлы были созданы для данного устройства uinput? Модуль ядра uinput не предоставляет ioctl для получения этой информации. Один из возможных подходов - опросить файловую систему сразу после создания устройства uinput, чтобы увидеть, какие файлы появляются, но этот подход не работает из-за гонок с другими устройствами, как реальными, так и uinput, которые также подключаются или создаются одновременно., Я что-то пропускаю или мне нужно взломать ядро, чтобы получить эту информацию?
2 ответа
Если вы посмотрите в sysfs, вы можете найти свою информацию. После того, как вы создали устройство uinput, выполните:
$ ls /sys/class/input/
event0 event1 ... eventN
input0 input2 ... input19 ... inputN
mouse0 mouse1 ... mouseN
mice
$ ls /sys/devices/virtual/input/
input19 mice
Обратите внимание, что вы можете найти виртуальное устройство по другому пути. В этом случае input19 - это мое устройство ввода данных. Какое корреспондентное устройство char?
$ ls /sys/devices/virtual/input/input19/
event14 name id ...
Мое устройство char /dev/input/event14
, я знаю это input19
мое устройство ввода, потому что я единственный пользователь, который создает устройства ввода. Если вы хотите быть уверены, вы должны прочитать его имя атрибута sysfs и убедиться, что это действительно ваше устройство
$ cat /sys/devices/virtual/input/input19/name
foo-keyboard-201303261446
Вы можете получить информацию о ваших новых устройствах uinput, читая сообщения ядра:
$ dmesg | tail -n 7
input: foo-keyboard-201303261445 as /devices/virtual/input/input14
input: foo-keyboard-201303261445 as /devices/virtual/input/input15
input: foo-keyboard-201303261445 as /devices/virtual/input/input16
input: foo-keyboard-201303261445 as /devices/virtual/input/input17
input: foo-keyboard-201303261446 as /devices/virtual/input/input18
input: foo-keyboard-201303261446 as /devices/virtual/input/input19
input: foo-keyboard-201303261446 as /devices/virtual/input/input20
Из вашей программы вы можете прочитать из /dev/kmsg
и поймать ваше событие. Может быть, вы можете открыть устройство /dev/kmsg
, промой, подожди select()
пока вы не получите уведомление uinput.
Альтернативой является использование libudev для получения вашего устройства uinput. Взгляните на следующую ссылку: руководство по libudev
ОБНОВЛЕНИЕ: благодаря вашему вопросу я улучшил свою библиотеку libuinput, доступную на github: libuinput от Federico. Я реализовал решение, которое использует устройство hte kmsg.
ОБНОВЛЕНИЕ: в 2014 году Linux uinput
драйвер был улучшен (git SHA1 e3480a61fc). Теперь можно получить путь sysfs непосредственно из uinput
водитель с помощью следующего ioctl
команда:
/**
* UI_GET_SYSNAME - get the sysfs name of the created uinput device
*
* @return the sysfs name of the created virtual input device.
* The complete sysfs path is then /sys/devices/virtual/input/--NAME--
* Usually, it is in the form "inputN"
*/
#define UI_GET_SYSNAME(len) _IOC(_IOC_READ, UINPUT_IOCTL_BASE, 300, len)
Так что, если у вас есть возможность использовать ядро Linux более свежего, чем 3.13, вы можете использовать выше ioctl
улучшить ваш код, который использует uinput.
Это лучший способ, который я нашел до сих пор, в сочетании с ответом, приведенным здесь, я бы сделал что-то вроде:
Как получить имя (путь) устройства, созданного uinput
char sysfs_device_name[16];
ioctl(uinput_fd_after_create, UI_GET_SYSNAME(sizeof(sysfs_device_name)), sysfs_device_name);
printf("/sys/devices/virtual/input/%s\n", sysfs_device_name);
//Now retrieve all files in that folder and grep for event* then
send_input_to_fd = open("the_event[n]", O_WRONLY | O_NDELAY);
Теперь send_input_to_fd должен быть правильным FD для отправки событий.