可以在C中读取但不能写入进程文件

可以在C中读取但不能写入进程文件,c,linux,screen-brightness,C,Linux,Screen Brightness,我正在写一个C程序来改变屏幕亮度,因为xbacklight在我的环境下不工作。解决方案应该是本机C,没有系统函数,因为程序应该可以作为普通用户通过setuid执行。调用外部shell命令或脚本会导致内核忽略此位 读取控制亮度的proc文件可以很好地工作,但是使用C写入它不会产生任何结果,即使我以root用户身份运行程序。fprintf调用返回-130,表示有错误。作为一个健全的检查,我包括了一个使用系统作为注释的工作解决方案 [...] const char*brightness=/sys/cl

我正在写一个C程序来改变屏幕亮度,因为xbacklight在我的环境下不工作。解决方案应该是本机C,没有系统函数,因为程序应该可以作为普通用户通过setuid执行。调用外部shell命令或脚本会导致内核忽略此位

读取控制亮度的proc文件可以很好地工作,但是使用C写入它不会产生任何结果,即使我以root用户身份运行程序。fprintf调用返回-130,表示有错误。作为一个健全的检查,我包括了一个使用系统作为注释的工作解决方案

[...] const char*brightness=/sys/class/backlight/intel_backlight/brightness; f=FOpen亮度!strncmpargv[1],get,3?r:rw; [...] int获得亮度{ int buff; fscanff,%d,&buff; 返回buff; } int setint i{ i=MAX0,MIN255,i; fprintff,%d,i; printf%d,i; //char*cmd=char*malloc59*sizeofchar; //snprintfcmd,59,回波%d>%s,i,亮度; //systemcmd; //freecmd; } rw不是fopen3的mode参数的有效参数。要使用fopen3以读/写模式打开文件,应使用r+

使用rw是未定义的行为-在Linux/glibc中,它将被视为单个r,文件将以只读模式打开,printf->write将失败

一般来说,对如此小的文件使用缓冲i/o不是一个非常明智的想法。如果需要将格式化数据写入文件描述符,则应查看dprintf3


另外,我只需要在setuid程序中使用一个固定值列表,而不必验证参数,并注意验证代码本身不会成为一种负担,等等。

为什么要使用rw模式?失败后的错误是什么?您的代码不会检查fprintf失败。。。?使用sterror或perror获取人类可读的错误。fprintff,%d\n,i;更好吗?@MarkPlotnick在/sys和/proc filelet中写入的值不必换行终止。要写入/proc,您的进程必须以root权限运行。您是否确认echo 5>/sys/class/backlight/intel\u backlight/brightness确实会改变亮度?某些发行版实现实际上不接受亮度的更改。您应该阅读/sys/class/backlight/intel\u backlight/max\u brightness来设置可接受值的上限。我相信这个答案没有抓住要点,请不要认为您确定的问题是错误的……真的,您是否错过了devpath的所有元素必须是真实目录。指向/sys/设备的符号链接必须始终解析为其实际目标,并且必须使用目标路径访问设备。这样,设备的devpath与事件时使用的内核的devpath匹配。我匹配,并且在尝试写入sysfs上包含符号链接的路径后,fclose后的简单策略或正确验证会导致对包含符号链接的路径的无效访问。如果你真的认为这只是一个建议,你可以测试一下,然后告诉kernel.org的人,他们的文档是错的?别误会我,我不是在批评你。从正常的文件读/写角度来看,这是非常不明显的行为。通常,链接是用于所有实际用途的文件,在本例中,accept.strace是跟踪系统调用(如open2或write2),而不是跟踪库函数(如fprintf3或fclose3)。你永远不会写路径,但是你打开了一个路径,如果是符号链接,它将被内核解析,然后写入open2返回的文件描述符。而EINVAL不是无效访问,而是无效参数。
f = fopen(brightness, (!strncmp(argv[1], "get", 3)) ? "r" : "rw");