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
相关产品推荐
相关产品推荐

