问题
I am writing a program which monitors through select()
on the keyboard and mouse device files. It waits for any write operation (this should happen when there is a keystroke or mouse movement) on those files and as soon as there is a write operation, some jobs are executed.
But it's not working. My code is given below.
#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");
}
}
}
When I execute the program it produces output like this,
[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
even though I am not pressing any key. Also, the mouse device file is never selected by select(), even though there is a physical mouse movement.
What am I doing wrong?
回答1:
You need to reinitialize your fd sets before every select
call. So, the loop in your program would look like:
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
}
Also, per User1's comment on your same question on Stack Overflow, you need to open the devices for reading, because you are trying to read data from them:
// Open device for reading (do you mean to use "/dev/input/mice" here?)
if ((mouse_fd = open("/dev/input/event3", O_RDONLY)) == -1)
Linux includes a select_tut(2) tutorial manpage with explanations of how to use select
and an example program which can be useful as a reference. "Select Law" #11 reminds you that you need to reinitialize your fd sets before each call to select
.
来源:https://stackoverflow.com/questions/12632630/select-isnt-responding-to-writing-on-dev-input-mice