为什么 Linux 的 sendfile() 与 /dev/zero 不兼容?



为什么sendfile与/dev/zero不兼容?为什么这个代码是

#include <iostream>
#include <sys/sendfile.h>
#include <fcntl.h>
#include <string.h>
int main(){
int f1 = fileno(tmpfile());
int devzero = open("/dev/zero", O_RDONLY);
if(f1 < 0 || devzero < 0){
throw std::runtime_error("Failed to open files");
}
ssize_t sent = sendfile(f1, devzero, 0, 1);
std::cout << "sent " << sent << " bytes. errno " << errno << " strerror " << strerror(errno) << std::endl;
return 0;
}

一致输出

sent -1 bytes. errno 22 strerror Invalid argument

/dev/zero是一个特殊的文件。它不代表磁盘上的文件。

来自sendfile文档:

The in_fd argument must correspond to a file which supports mmap(2)-like operations (i.e., it cannot be a socket).
...
EINVAL Descriptor is not valid or locked, or an mmap(2)-like operation is not available for in_fd, or count is negative.
EINVAL out_fd has the O_APPEND flag set.  This is not currently supported by sendfile().

内核源代码的这些部分正在报告错误:

if (unlikely(out->f_flags & O_APPEND))
return -EINVAL;
ret = rw_verify_area(WRITE, out, opos, len);

我做了一些测试。从tmpfile((、一个常规文件和/dev/zero进行读取是可行的。写入常规文件是可行的,但写入/dev/zero会失败其中一项检查(O_APPEND权限或rw_verify_area(((。

最新更新