Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux (打开和写入)与(fopen和写入)到内核/proc/_Linux_Linux Kernel_Kernel_Fwrite - Fatal编程技术网

Linux (打开和写入)与(fopen和写入)到内核/proc/

Linux (打开和写入)与(fopen和写入)到内核/proc/,linux,linux-kernel,kernel,fwrite,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);

我有一只很奇怪的虫子。如果我这样做:

    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指令)

FPUT与puts的问题相同

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


知道发生了什么吗?

可能是缓冲区的问题

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

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


为了确保这一点,请尝试使用两个版本的程序运行
strace
,并比较输出。如果您愿意,请发布它们以获取其他注释。

fwrite缓冲数据,因此您需要执行刷新调用,其余数据应存储在文件中。@ClaudioCorsi:
fclose()
自动刷新文件。这是一个自定义驱动程序,但没有什么特别之处。这个条目是用通常的create\u proc\u条目创建的。@gregoiregentil:啊,驱动程序是你写的?那么,也许你是在处理错误的书写。可能您的单个
fwrite()
调用已从glibc内部转换为对
write()
的多个成功调用。正如我所说,您可以使用
strace
检查它。这里有两个strace:非常奇怪的是,fwrite如何执行mmap2,然后只写入1024characters@gregoiregentil:mmap2
mmap2
是分配文件缓冲区的匿名映射(大malloc通常是mmamap)。注意1024字节的
write()
如何在
EINVAL
中失败
fwrite
注意准备处理此类错误:“如果发生错误,则流的文件位置指示器的结果值未指定”。您可以或应该使用
ferror()
检查发生了什么。