3

我正在编写一个通过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");
            }
   }
}

当我执行程序时,它会产生这样的输出,

[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

即使我没有按任何键。此外,即使有物理鼠标移动,select() 也不会选择鼠标设备文件。

我究竟做错了什么?

4

1 回答 1

4

您需要在每次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
}

此外,根据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)

Linux 包括一个select_tut(2)教程手册页,其中解释了如何使用select和一个示例程序,可用作参考。“Select Law”#11 提醒您在每次调用select.

于 2012-09-27T13:04:44.750 回答