首页 > 解决方案 > 为什么我的代码无法使用 uinput 创建简单的输入设备?

问题描述

我正在尝试在 linux 中学习使用/dev/uinput并从kernel.org/doc/html/v4.12/input/uinput.html复制简单的代码,如下所示:

#include <linux/uinput.h>

void emit(int fd, int type, int code, int val)
{
   struct input_event ie;

   ie.type = type;
   ie.code = code;
   ie.value = val;
   /* timestamp values below are ignored */
   ie.time.tv_sec = 0;
   ie.time.tv_usec = 0;

   write(fd, &ie, sizeof(ie));
}

int main(void)
{
   struct uinput_setup usetup;

   int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);


   /*
    * The ioctls below will enable the device that is about to be
    * created, to pass key events, in this case the space key.
    */
   ioctl(fd, UI_SET_EVBIT, EV_KEY);
   ioctl(fd, UI_SET_KEYBIT, KEY_SPACE);

   memset(&usetup, 0, sizeof(usetup));
   usetup.id.bustype = BUS_USB;
   usetup.id.vendor = 0x1234; /* sample vendor */
   usetup.id.product = 0x5678; /* sample product */
   strcpy(usetup.name, "Example device");

   ioctl(fd, UI_DEV_SETUP, &usetup);
   ioctl(fd, UI_DEV_CREATE);

   /*
    * On UI_DEV_CREATE the kernel will create the device node for this
    * device. We are inserting a pause here so that userspace has time
    * to detect, initialize the new device, and can start listening to
    * the event, otherwise it will not notice the event we are about
    * to send. This pause is only needed in our example code!
    */
   sleep(1);

   /* Key press, report the event, send key release, and report again */
   emit(fd, EV_KEY, KEY_SPACE, 1);
   emit(fd, EV_SYN, SYN_REPORT, 0);
   emit(fd, EV_KEY, KEY_SPACE, 0);
   emit(fd, EV_SYN, SYN_REPORT, 0);

   /*
    * Give userspace some time to read the events before we destroy the
    * device with UI_DEV_DESTOY.
    */
   sleep(1);

   //ioctl(fd, UI_DEV_DESTROY);
   close(fd);

   return 0;
}

它编译并成功运行,没有错误。xinput但我在终端中找不到使用此命令创建的任何设备。我还检查了/dev/input/,但在执行我的那个程序后没有发现任何变化。

我在 Ubuntu、Kali 上试过。我错过了什么?

标签: linuxuinput

解决方案


可能是帮助别人。

int i=0;
while(i<100){
i++;
sleep(1);
   emit(fd, EV_KEY, KEY_SPACE, 1);
   emit(fd, EV_SYN, SYN_REPORT, 0);
   emit(fd, EV_KEY, KEY_SPACE, 0);
   emit(fd, EV_SYN, SYN_REPORT, 0);
}

我发现当程序在循环中时,设备被创建了。在此期间,您可以使用xinput命令进行检查。程序结束后,即使我不调用,设备也会被销毁ioctl(fd,UI_DEV_DESTROY)


推荐阅读