Invalid argument when calling linux splice()
I wanted to try out the splice syscall. I have this function - it should copy content of one file to another:
static void test_splice( int in, int out ) {
int i = 0, rcvd = 0;
int filedes[2];
off_t off = 0;
if ( pipe( filedes ) < 0 ) {
perror( "Kicha pipe" );
exit( EXIT_FAILURE );
}
for ( i = 0; i < NUMLOOPS; ++i ) {
if ( ( rcvd = splice( in, NULL, filedes[1], NULL, BUFSIZE, SPLICE_F_MORE | SPLICE_F_MOVE ) ) < 0 ) {
perror( "splice" );
exit( EXIT_FAILURE );
}
if ( splice( filedes[0], NULL, out, NULL, rcvd, SPLICE_F_MORE | SPLIC开发者_如何学GoE_F_MOVE ) < 0 ) {
perror( "splice" );
exit( EXIT_FAILURE );
}
}
}
The second call to splice in first iteration returns EINVAL ( invalid argument from perror ) everytime - what could be the reason?
From splice(2)
:
ERRORS
...
EINVAL Target filesystem doesn't support splicing; target file is
opened in append mode; neither of the file descriptors refers to
a pipe; or offset given for nonseekable device.
...
OP's comment indicated that he opened the file in append mode.
I have no idea whether this is the best way of doing this, but this works for me:
http://vectrex.org.uk/mark/splicecopy.cpp
It creates one thread to read and another for writing. This may be unnecessary. The writing thread only appears to require one splice() call, but the reader does approximately every 64k on my system.
The above was tested on Fedora 13 x86_64 and appears to be able to copy larg(ish) files.
精彩评论