You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux select系统调用无法检测按键输入问题排查

Ubuntu 22.04.04随机自动输入字符问题排查及代码故障求助

我正在排查Ubuntu 22.04.04系统中随机出现未输入字符的问题,此前已在AskUbuntu提交相关提问。最初使用evtest逐个指定输入设备监听时,能看到随机字符显示,但evtest未记录对应的按键事件。为了能在按键事件发生时自动监听所有设备并定位触发源,我修改了evtest.c中的scan_devices函数,基于Linux select系统调用实现多输入设备监听逻辑。

但以root权限运行修改后的程序时,手动按键输入后字符正常显示,却未触发预期的设备触发提示。添加调试打印后发现,程序卡在rd = read(fd[i], ev, sizeof(ev));语句处。以下是修改后的代码及运行输出,恳请提供问题修复思路:

static char* scan_devices(void)
{
    struct dirent **namelist;
    int i, ndev, devnum;
    char *filename;
    int max_device = 0;

    ndev = scandir(DEV_INPUT_EVENT, &namelist, is_event_device, versionsort);
    if (ndev <= 0)
        return NULL;

    fprintf(stderr, "Available devices:\n");

    for (i = 0; i < ndev; i++){
        char fname[300];
        int fd = -1;
        char name[256] = "???";

        snprintf(fname, sizeof(fname),
             "%s/%s", DEV_INPUT_EVENT, namelist[i]->d_name);
        fd = open(fname, O_RDONLY);
        if (fd < 0)
            continue;
        ioctl(fd, EVIOCGNAME(sizeof(name)), name);

        fprintf(stderr, "%s:    %s\n", fname, name);
        close(fd);

        sscanf(namelist[i]->d_name, "event%d", &devnum);
        if (devnum > max_device)
            max_device = devnum;

        free(namelist[i]);
    }//end for

    /* open and monitor nuevents files*/

    struct input_event ev[64];

    int rd;
    fd_set rdfs;
    int nuevents=28;
    int fd[28]; //should be equal to nuevents
    int ret=0;

    printf("Size of rdfs %d B \nStart Monitor \n", (int) sizeof(rdfs));

    /* Next we clear the file descriptors*/
    FD_ZERO(&rdfs);

    /* We need to open each device and then add them to the file descriptors */
    for (i = 0; i < nuevents; i++){
        char fname[300];

        snprintf(fname, sizeof(fname),
             "%s/%s", DEV_INPUT_EVENT, namelist[i]->d_name);
        fd[i] = open(fname, O_RDONLY);
        if (fd[i]<0){
            printf("error file %d \n",(int)i);
            return 0;

        }// end if

        FD_SET(fd[i], &rdfs);

    }// end for

    while (!stop) {
        ret = select(nuevents, &rdfs, NULL, NULL, NULL);
        if (stop)
            break;
        if (ret < 0){
            printf("ret failure");
            exit (EXIT_FAILURE);
        }// end if

        for (i=0;i<nuevents;i++){
            if (FD_ISSET(i,&rdfs)){
                printf("received data on device %d\n",(int)i);
                rd = read(fd[i], ev, sizeof(ev));

                if (rd < (int) sizeof(struct input_event)) {
                    printf("expected %d bytes, got %d\n", (int) sizeof(struct input_event), rd);
                    perror("\nevtest: error reading");
                    return "error";
                }   // end of if

            }// end of if
        }// end of for

    }// end of while

    for (i = 0; i < nuevents; i++){
        ioctl(fd[i], EVIOCGRAB, (void*)0); /* Use IO CTRL to release device*/
    }//end for

    return "done";
}

运行输出示例:

No device specified, trying to scan all of /dev/input/event*
Available devices:  
/dev/input/event0:  Power Button  
/dev/input/event1:  Sleep Button  
/dev/input/event2:  Lid Switch  
/dev/input/event3:  Power Button  
/dev/input/event4:  AT Translated Set 2 keyboard  
/dev/input/event5:  System76 ACPI Hotkeys  
/dev/input/event6:  FTCS1000:00 2808:0102 Mouse  
/dev/input/event7:  FTCS1000:00 2808:0102 Touchpad  
/dev/input/event8:  MOSART Semi. 2.4G INPUT DEVICE  
/dev/input/event9:  MOSART Semi. 2.4G INPUT DEVICE Mouse  
/dev/input/event10: MOSART Semi. 2.4G INPUT DEVICE Consumer Control   
/dev/input/event11: MOSART Semi. 2.4G INPUT DEVICE System Control  
/dev/input/event12: MOSART Semi. 2.4G INPUT DEVICE  
/dev/input/event13: Lite-On Technology Corp. USB Multimedia Keyboard  
/dev/input/event14: Lite-On Technology Corp. USB Multimedia Keyboard System Control  
/dev/input/event15: Lite-On Technology Corp. USB Multimedia Keyboard Consumer Control  
/dev/input/event16: Lite-On Technology Corp. USB Multimedia Keyboard  
/dev/input/event17: Video Bus  
/dev/input/event18: Intel HID events  
/dev/input/event19: HDA Intel PCH Mic  
/dev/input/event20: HDA Intel PCH Headphone  
/dev/input/event21: HDA Intel PCH HDMI/DP,pcm=3  
/dev/input/event22: HDA Intel PCH HDMI/DP,pcm=7  
/dev/input/event23: HDA Intel PCH HDMI/DP,pcm=8  
/dev/input/event24: HDA Intel PCH HDMI/DP,pcm=9  
/dev/input/event25: HDA NVidia HDMI/DP,pcm=3  
/dev/input/event26: HDA NVidia HDMI/DP,pcm=7  
/dev/input/event27: HDA NVidia HDMI/DP,pcm=8  
/dev/input/event28: HDA NVidia HDMI/DP,pcm=9  
Size of rdfs 128 B  
Start Monitor 
received data on device 7  
a    
a  

内容的提问来源于stack exchange,提问作者Kevin Johnson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 21:05:14