sendfile()中带有两个常规文件的参数无效

我试图在Linux 2.6.32下testingsendfile()系统调用,以便在两个常规文件之间零拷贝数据。 据我了解,它应该工作:从2.6.22, sendfile()已经实现了使用splice() ,并且input文件和输出文件都可以是常规文件或套接字。

以下是sendfile_test.c的内容:

 #include <sys/sendfile.h> #include <fcntl.h> #include <stdio.h> int main(int argc, char **argv) { int result; int in_file; int out_file; in_file = open(argv[1], O_RDONLY); out_file = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644); result = sendfile(out_file, in_file, NULL, 1); if (result == -1) perror("sendfile"); close(in_file); close(out_file); return 0; } 

当我运行以下命令时:

 $ gcc sendfile_test.c $ ./a.out infile outfile 

输出是

 sendfile: Invalid argument 

而当运行

 $ strace ./a.out infile outfile 

输出包含

 open("infile", O_RDONLY) = 3 open("outfile", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 4 sendfile(4, 3, NULL, 1) = -1 EINVAL (Invalid argument) 

我究竟做错了什么?

你忘了检查argc是否等于3 ,即你打开输出文件的名字argv[2]但只给你的程序一个参数(你open(2)open(2)没有检查错误open(2)

您可以使用strace(1)来查找哪个系统调用失败。

编辑:

这看起来像老的内核对我来说。 相同的源(模错误检查)在2.6.33.4 #3 SMP2.6.33.4 #3 SMP工作。 另外,你只是复制一个字节的任何特定原因?

 #include <sys/sendfile.h> #include <err.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main( int argc, char *argv[] ) { int in_file, out_file; if ( argc != 3 ) { fprintf( stderr, "usage: %s <in-file> <out-file>\n", argv[0] ); exit( 1 ); } if (( in_file = open( argv[1], O_RDONLY )) == -1 ) err( 1, "open" ); if (( out_file = open( argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644 )) == -1 ) err( 1, "open(2)" ); if ( sendfile( out_file, in_file, NULL, 4096 ) == -1 ) err( 1, "sendfile" ); exit( 0 ); } 

跟踪:

 nickf@slack:~/csource/linux/splice$ cc -Wall -pedantic -ggdb -g3 -o sf sndf.c nickf@slack:~/csource/linux/splice$ strace ./sf Makefile mm ... open("Makefile", O_RDONLY) = 3 open("mm", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 4 sendfile(4, 3, NULL, 4096) = 239 exit_group(0) = ? nickf@slack:~/csource/linux/splice$ diff Makefile mm nickf@slack:~/csource/linux/splice$