开发者

Invalid argument when calling linux splice()

开发者 https://www.devze.com 2022-12-25 22:54 出处:网络
I wanted to try out the splice syscall. I have this function - it should copy content of one file to another:

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消