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
}

また、 Stack Overflow に関する同じ質問に対する User1 のコメントに従って、デバイスからデータを読み取ろうとしているため、読み取り用にデバイスを開く必要があります。

// 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 は、 を呼び出すたびに fd セットを再初期化する必要があることを思い出させますselect

于 2012-09-27T13:04:44.750 に答える