linux - (open + write) 与 (fopen + fwrite) 到 kernel/proc/

标签 linux linux-kernel kernel fwrite

我有一个非常奇怪的错误。如果我这样做:

    int fd = open("/proc/...", O_WRONLY);
    write(fd, argv[1], strlen(argv[1]));
    close(fd);

一切正常,包括长度 > 1024 的非常长的字符串。

如果我这样做:

    FILE *fd = fopen("/proc/...", "wb");
    fwrite(argv[1], 1, strlen(argv[1]), fd);
    fclose(fd);

该字符串被剪切为大约 1024 个字符。

我正在运行带有 3.4 内核的 ARM 嵌入式设备。我已经在内核中进行了调试,当我到达很早的函数 vfs_write 时,我发现字符串已经被剪切(我发现这个函数带有 WARN_ON 指令来获取堆栈)。

fputs 与 puts 的问题是一样的。

如果我写入标准 rootfs 文件,我可以使用 fwrite 来处理非常长的字符串 (>1024)。所以问题实际上与内核如何处理/proc 有关。

知道发生了什么吗?

最佳答案

问题可能出在缓冲区上。

问题是特殊文件,例如 /proc 中的文件,嗯...很特殊,它们并不总是简单的字节流,并且必须以特定的大小和/或偏移量写入(或读取)。您没有说明要写入哪个文件,因此无法确定。

然后,对 fwrite() 的调用假定输出 fd 是一个简单的字节流,因此它会执行一些巧妙的操作,例如缓冲、拼接和复制给定的数据。在常规文件中它会正常工作,但在特殊文件中,可能会发生有趣的事情。

为了确定起见,请尝试使用程序的两个版本运行 strace 并比较输出。如果您愿意,请发布它们以获取更多评论。

关于linux - (open + write) 与 (fopen + fwrite) 到 kernel/proc/,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27583751/

相关文章:

python - 如何在 python 中对 Linux 上具有多个分隔符的行使用 split 和 strip

linux - systemtap的内部结构

linux - 线程间的上下文切换

architecture - 抢占和上下文切换的区别

linux - 这些数据是随机的还是有意义的?

c# - Linux 中的 Visual Studio Code - 将 F5(调试)从 "dotnet build"重新映射到 "msbuild csproj"?

c - 我应该如何读取或写入 APIC 寄存器 0x​​104567910?

linux - 如何使用proc文件打印mem_map的信息?

linux - 在 gdb 断点处运行命令,c 或 cont 都不起作用

linux - 内核驱动程序 - ZedBoard - Linux 在访问地址后挂起