文件 i/o 操作失败的原因 = -1 EACCES(权限被拒绝)

文件 i/o 操作失败的原因 = -1 EACCES(权限被拒绝)

我的程序中存在一个错误,我通过使用 strace 缩小了范围,出现以下错误 -

open("/sys/class/gpio/gpio17/value", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = -1 EACCES (Permission denied)
open("/sys/class/gpio/gpio17/direction", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = -1 EACCES (Permission denied)

有关背景信息,您可以在此处阅读此主题 -https://stackoverflow.com/questions/39524234/bug-with-writing-to-file-in-linux-sys-class-gpio

我单独运行了 3 次测试,一次正常运行,一次指定了 sudo,另一次指定了故意延迟。以下是这些运行的相关 strace 结果 -

Normal

open("/sys/class/gpio/export", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/unexport", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/export", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/gpio17/value", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = -1 EACCES (Permission denied)
open("/sys/class/gpio/gpio17/direction", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = -1 EACCES (Permission denied)
open("/sys/class/gpio/unexport", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3

sudo

open("/sys/class/gpio/export", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/unexport", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/export", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/gpio17/value", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/gpio17/direction", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 4
open("/sys/class/gpio/unexport", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3

Delayed

("/sys/class/gpio/export", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/unexport", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/export", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/gpio17/value", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/gpio17/direction", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 4
open("/sys/class/gpio/unexport", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3

现在我尝试寻找这个错误,但我发现的只是 javascript、android 或 nodejs 错误,没有指向原始描述的链接。任何类型的信息都对我非常有益,所以感谢您的帮助:)

编辑- 如果相关,我将其作为 udev 规则/etc/udev/rules.d/99-com.rules-

SUBSYSTEM=="bcm2835-gpiomem", KERNEL=="gpiomem", GROUP="gpio", MODE="0660"
SUBSYSTEM=="gpio", KERNEL=="gpiochip*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:gpio /sys/class/gpio/export /sys/class/gpio/unexport ; chmod 220 /sys/class/gpio/export /sys/class/gpio/unexport'"
SUBSYSTEM=="gpio", KERNEL=="gpio*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:gpio /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/value ; chmod 660 /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/value'"

和 ls -l 输出 -

total 0
--w--w---- 1 root gpio 4096 Sep 16 07:13 export
lrwxrwxrwx 1 root root    0 Sep 16 07:13 gpio17 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpio17
lrwxrwxrwx 1 root root    0 Jul 31 05:23 gpiochip0 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpiochip0
--w--w---- 1 root gpio 4096 Sep 16 06:50 unexport

当前用户也是 GPIO 组的一部分。

答案1

我愿意把钱花在你的程序和udev.

显然,/sys/class/gpio/gpio17/value/sys/class/gpio/gpio17/direction节点是在 后的某个时刻创建的open("/sys/class/gpio/export", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3,最初它们可能由 拥有root:root,普通用户没有写访问权限。

然后 udev 规则生效,udev 调用 sh 来设置权限,但这需要一段时间;如果您open()之前尝试下一个,则会失败。

不知道有没有办法让你等待udev完成而不进行轮询。

相关内容