inotify事件后无法打开 devinputjs文件描述符

inotify事件后无法打开 devinputjs文件描述符,第1张

概述inotify事件后无法打开/ dev / input / js文件描述

我正在创build一个游戏库的linux模块,让你热插拔多个游戏杆,它使用inotify来观看/dev/input 。

我正在testing3个游戏杆:

首先,我连接2个 *** 纵杆。

然后我启动应用程序, *** 纵杆工作,我没有得到一个错误。

之后,我连接第三个游戏杆, perror给: /dev/input/Js1: Permission denIEd 。

当我检查ls -l /proc/<pID-of-process>/fd它列出了/dev/input/Js0和/dev/input/Js2 。

当我以root身份运行游戏杆时,所有游戏杆都可以正常工作。

这是如何初始化的:

CoInitialize尚未被调用 – (从无directxtk的库中加载gamepad.h)

为什么SDL不能在linux上检测我的ibuffalo游戏控制器(PocketCHIP)?

解释USB游戏杆轴

static voID createGamepad(char *locname){ char dirname[30]; int fd; snprintf(dirname,30,"/dev/input/%s",locname); fd = open(dirname,O_RDONLY | O_NONBLOCK,0); if(fd < 0){ perror(dirname); } } struct dirent *dir; DIR *d; int i,notifyfd,watch; // Attach notifications to check if a device connects/disconnects notifyfd = inotify_init(); watch = inotify_add_watch(notifyfd,"/dev/input",IN_CREATE | IN_DELETE); d = opendir("/dev/input"); i = 0; while((dir = readdir(d)) != NulL){ if(*dir->d_name == 'j' && *(dir->d_name + 1) == 's'){ createGamepad(dir->d_name,i); i++; } } closedir(d);

之后,inotify在while(1)循环中像这样处理它:

static bool canReadINotify(){ fd_set set; struct timeval timeout; FD_ZERO(&set); FD_SET(notifyfd,&set); timeout.tv_sec = 0; timeout.tv_usec = 0; return select(notifyfd + 1,&set,NulL,&timeout) > 0 && FD_ISSET(notifyfd,&set); } // InsIDe the event loop struct inotify_event ne; while(canReadINotify()){ if(read(notifyfd,&ne,sizeof(struct inotify_event) + 16) >= 0){ if(*ne.name != 'j' || *(ne.name + 1) != 's'){ continue; } if(ne.mask & IN_CREATE){ createGamepad(ne.name); } } }

它甚至可能与inotify或者我应该使用udev? 如果有可能,我该如何解决这个问题?

这很可能是一个竞争条件。 你会发现,当设备节点被创建时(通过udev使用mknod()调用),你会得到inotify事件,但是访问权限是由udev使用一个单独的chown()调用设置的,稍后一点点。

请参阅systemd src/udev/udev-node.c , node_permissions_apply() 。 在这种情况下, /dev/input/JsX不是符号链接,而是实际的设备节点; 至少在systemd之后,设备节点访问模式会在实际节点创建后的某个时间被设置。

一个可靠的解决方案是修改你的createGamepad()函数,以便在fd == -1 && errno == EACCES完全失败,而不是在短时间后重试; 至少几次,比如说一两秒钟。

然而, ninjalj指出了一个更好的建议 :使用访问权限更改作为触发器来检查设备节点。 这是通过使用IN_CREATE | IN_DELETE | IN_ATTRIBUTE来实现的 IN_CREATE | IN_DELETE | IN_ATTRIBUTE inotify_add_watch()函数中的IN_CREATE | IN_DELETE | IN_ATTRIBUTE !

(你也可以忽略createGamepad() open()==-1,errno==EACCES错误,因为它们很有可能是由这个竞争条件引起的,下面的IN_ATTRIBUTE inotify事件将会产生对同一个设备的访问。 )

在ninjalj的评论之前,我本人曾经使用过一系列的输入设备,而另外一个是用于“可能的”输入设备,在短暂的暂停之后可能需要重试以决定它们是否可用,但是我认为他的建议好多了

需要/想要一个例子?

总结

以上是内存溢出为你收集整理的inotify事件后无法打开/ dev / input / js文件描述符全部内容,希望文章能够帮你解决inotify事件后无法打开/ dev / input / js文件描述符所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1274137.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存