为什么`ioctl(fd,EVIOCGRAB,1)`有时会导致密钥垃圾邮件?
我正在尝试编写自己的“键盘驱动程序”(没有实际编写内核模块),通过抓取键盘,我认为是userland中最低级别的抽象: /dev/input/event*
。
如果您将ioctl(fd, EVIOCGRAB, UNGRAB)
的第一个更改更改为ioctl(fd, EVIOCGRAB, GRAB)
以下代码执行此操作。
// gcc main.c -o main #include #include #include #include #include #include #define EXIT_KEY KEY_ESC #define UNGRAB 0 #define GRAB 1 const char* kbd_device = "/dev/input/event4"; // ------------------------------------------------------------------------------------------------ int main(void){ int fd = open(kbd_device, O_RDONLY); if(fd == -1){ printf("Cannot open %s. %s.\n", kbd_device, strerror(errno)); return -1; } if(ioctl(fd, EVIOCGRAB, UNGRAB)) printf("Couldn't grab %s. %s.\n", kbd_device, strerror(errno)); else printf("Grabbed %s!\n", kbd_device); while(1){ struct input_event event; read(fd, &event, sizeof(event)); if (event.type == EV_KEY && event.value >= 0 && event.value <= 2){ printf("%d %3d\n", event.value, event.code); if(event.code == EXIT_KEY){ ioctl(fd, EVIOCGRAB, UNGRAB); close(fd); return 0; } } } }
问题
- 如果我运行
gcc main.c -o main && sudo ./main
,一切都按预期工作。 - 如果先编译然后我运行
sudo ./main
,则终端会不停地向下滚动,就像按住RETURN键一样。
为什么会这样?
笔记
- 我正在运行Ubuntu 14.04
- 在我的平台上,
/dev/input/event4
恰好是键盘
动机
我正在尝试编写一个键盘“驱动程序”,它既可以在X上运行,也可以在X上运行(例如,一个TTY)。
我理解X11的键盘库/扩展名是XKB。 我认为TTY的键盘库是linux/divers/tty/vt/keyboard.c
( 源码 ),它使用的初始键盘映射是linux/drivers/tty/vt/defkeymap.map
( 源码 ),可以修改通过使用loadkeys
(源在这里 )。 如果我错了,请纠正我。
当你输入
gcc main.c -o main && sudo ./main ↵
GCC需要一些时间,因此。键已经在./main
运行时./main
。
当你输入
sudo ./main ↵
一旦你按下↵ ,终端就会向shell发送换行符,然后开始执行./main
。 然后,您的程序会看到↵发布的事件,但不是您的终端,因为您的程序已经抓住了输入设备。 因此,到终端看起来↵被卡住了,所以它继续产生换行符。