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

标签 c linux screen-brightness

我正在编写一个 C 程序来更改屏幕亮度,因为 xbacklight 在我的情况下不起作用。解决方案应该是原生 C(没有 system() 函数),因为该程序应该可以通过 setuid 作为普通用户执行。调用外部 shell 命令或脚本会导致内核忽略此位。

读取控制亮度的 proc 文件工作正常,但使用 C 写入它不会产生任何结果,即使我以 root 身份运行程序也是如此。 fprintf 调用返回 -130,表示错误。作为完整性检查,我包含了一个使用 system() 作为注释的工作解决方案。

[...]
const char* brightness = "/sys/class/backlight/intel_backlight/brightness";
f = fopen(brightness, (!strncmp(argv[1], "get", 3)) ? "r" : "rw");
[...]

int get_brightness() {
  int buff;
  fscanf(f, "%d", &buff);
  return buff;
}

int set(int i) {
  i = MAX(0, MIN(255, i));
  fprintf(f, "%d", i);
  printf("%d", i);
  //char *cmd = (char*) malloc(59 *sizeof(char));
  //snprintf(cmd, 59, "echo %d > %s", i, brightness);
  //system(cmd);
  //free(cmd);
}

最佳答案

f = fopen(brightness, (!strncmp(argv[1], "get", 3)) ? "r" : "rw");

"rw" 不是 fopen(3)mode 参数的有效参数。要使用 fopen(3) 在读/写模式下打开文件,您应该使用 "r+"

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

通常,对如此小的文件使用缓冲 I/O 并不是一个明智的主意。如果您需要将格式化数据写入文件描述符,您应该查看 dprintf(3)

此外,我会在 setuid 程序中使用固定值列表,而不必验证参数,并注意验证代码本身不会成为一种责任,等等。

关于可以在C中读取但不能写入proc文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56979485/

相关文章:

windows-phone-7 - WP7下如何防止屏幕变暗?

android - 如何在 Marshmallow 中授予更改屏幕亮度的权限

c - 如何在C程序中多次从stdin读取数据

linux - 如何使用 linux 系统调用杀死生成的 "/bin/sh -c"及其所有子进程

C:读取一个目录下的所有*.txt文件

linux - 如何删除超过 X 天的文件并打印已删除文件的列表

java - 使用 nohup standalone full 启动 WildFly

android - 以编程方式更改 6.0 中的屏幕亮度

c - 使用 Xlib 发现面板的大小

c - 没有编译错误,但给定输入时崩溃