我正在编写一个程序,通过select()键盘和鼠标设备文件进行监控.它等待这些文件上的任何写操作(这应该在键击或鼠标移动时发生),并且只要有写操作,就会执行一些作业.
但它不起作用.我的代码如下.
#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<linux/input.h>
#include<linux/uinput.h>
#include<sys/time.h>
#include<unistd.h>
void main()
{
int mouse_fd,kbd_fd,fd_max;
struct input_event ev;
fd_set rfs,wfs;
if((mouse_fd=open("/dev/input/event3",O_WRONLY))==-1)
{
printf("opening mouse device file has failed \n");
}
else
{
printf("opening mouse device file has been successfull \n");
}
if((kbd_fd=open("/dev/input/event2",O_WRONLY))==-1)
{
printf("opening keyboard device file has failed \n");
}
else
{
printf("opening keyboard device file has been successfull \n");
}
FD_ZERO(&rfs);
FD_ZERO(&wfs);
FD_SET(mouse_fd,&rfs);
FD_SET(kbd_fd,&rfs);
FD_SET(mouse_fd,&wfs);
FD_SET(kbd_fd,&wfs);
if(mouse_fd>kbd_fd)
{
fd_max=mouse_fd;
}
else
{
fd_max=kbd_fd;
}
while(1)
{
select((fd_max+1),&rfs,NULL,NULL,NULL);
sleep(2);
if(FD_ISSET(mouse_fd,&rfs))
{
printf("test mouse \n");
}
if(FD_ISSET(kbd_fd,&rfs))
{
printf("test keyboard \n");
}
}
}
Run Code Online (Sandbox Code Playgroud)
当我执行程序时,它产生这样的输出,
[root@localhost Project]# gcc select.c
[root@localhost Project]# ./a.out
opening mouse device file has been successfull
opening keyboard device file has been successfull
test keyboard
test keyboard
test keyboard
test keyboard
test keyboard
test keyboard
test keyboard
test keyboard
test keyboard
Run Code Online (Sandbox Code Playgroud)
即使我没有按任何键.此外,即使存在物理鼠标移动,select()也不会选择鼠标设备文件.
我究竟做错了什么?
您需要在每次select通话前重新初始化您的fd集.所以,程序中的循环看起来像:
while(1)
{
FD_ZERO(&rfs);
FD_ZERO(&wfs);
FD_SET(mouse_fd, &rfs);
FD_SET(kbd_fd, &rfs);
FD_SET(mouse_fd, &wfs);
FD_SET(kbd_fd, &wfs);
select((fd_max+1),&rfs,NULL,NULL,NULL);
// proceed normally
}
Run Code Online (Sandbox Code Playgroud)
另外,根据User1对Stack Overflow上相同问题的评论,您需要打开设备进行读取,因为您正在尝试从中读取数据:
// Open device for reading (do you mean to use "/dev/input/mice" here?)
if ((mouse_fd = open("/dev/input/event3", O_RDONLY)) == -1)
Run Code Online (Sandbox Code Playgroud)
Linux包含一个select_tut(2)教程手册页,其中包含如何使用的说明select以及可用作参考的示例程序."选择法律"#11提醒您需要在每次调用之前重新初始化您的fd集select.