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:mmap2mmap2
是分配文件缓冲区的匿名映射(大malloc通常是mmamap)。注意1024字节的write()
如何在EINVAL
中失败fwrite
注意准备处理此类错误:“如果发生错误,则流的文件位置指示器的结果值未指定”。您可以或应该使用ferror()
检查发生了什么。