如何确定与输入设备对应的文件?

时间:2013-03-25 19:48:34

标签: linux file linux-device-driver

在linux中创建uinput设备时,会在文件系统中创建与该设备对应的一个或多个事件文件。 (例如,如果我创建一个输入鼠标,则创建文件/ dev / input / mouseN。)但是,如何确定为给定的输入设备创建了哪些文件? uinput内核模块似乎没有提供任何ioctl来获取该信息。一种可能的方法是在创建uinput设备之后立即轮询文件系统以查看显示的文件,但是这种方法不起作用,因为与其他设备(包括真实输入和uinput)的比赛也在同一时间插入或创建。我是否忽略了某些内容,或者我必须破解内核才能获得此信息?

2 个答案:

答案 0 :(得分:6)

如果你查看 sysfs ,你可以找到你的信息。创建完输入设备后,请执行以下操作:

$ 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 ...

我的字符设备是/dev/input/event14。我知道input19是我的输入设备,因为我是唯一一个创建输入设备的用户。如果您想确定,您必须阅读其sysfs属性 name 并验证它确实是您的设备

$ cat /sys/devices/virtual/input/input19/name
foo-keyboard-201303261446

您可以通过阅读内核消息来检索有关新输入设备的信息:

$ 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(),直到您收到输入通知。

另一种方法是使用 libudev 来检索您的输入设备。请查看以下链接:libudev tutorial

更新:感谢您的问题,我改进了github上提供的libuinput库:libuinput by Federico。我实现了使用hte kmsg 设备的解决方案。

更新:2014年,Linux uinput驱动程序得到了改进(git SHA1 e3480a61fc)。现在可以使用以下uinput命令直接从ioctl驱动程序获取sysfs路径:

/**
 * 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)

因此,如果你有可能使用比3.13更新的Linux内核,你可以使用上面的ioctl来改进使用uinput的代码。

答案 1 :(得分:1)

这是我到目前为止找到的最好方法,结合这里给出的答案,我会做的事情如下:

How to get name (path) of uinput created device

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。