2010-04-05 5 views
5

Chciałem wypróbować połączenie splicingowe. Mam tej funkcji - należy skopiować zawartość jednego pliku do drugiego:Nieprawidłowy argument podczas wywoływania linux splice()

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 | SPLICE_F_MOVE) < 0) { 
         perror("splice"); 
         exit(EXIT_FAILURE); 
       } 
     } 
} 

Drugie wezwanie do splatać w pierwszej iteracji zwraca EINVAL (nieprawidłowy argument, z perror) za każdym razem - co może być przyczyną?

+0

Jakiego rodzaju system (i) plików to pliki? – Duck

+0

Zarówno ext3, ale także próbowałem czytać z/dev/zero i pisać do/dev/null z tym samym błędem. –

+4

Właśnie go rozwiązałem - otworzyłem plik używając fopen z trybem "a +" - po zmianie na "w" - zadziałało. –

Odpowiedz

-1

nie mam pojęcia, czy jest to najlepszy sposób to zrobić, ale to działa na mnie:

http://vectrex.org.uk/mark/splicecopy.cpp

Tworzy jeden wątek, aby przeczytać, a drugi do pisania. To może być niepotrzebne. Piszący wątek wydaje się wymagać tylko jednego połączenia splice(), ale czytnik robi mniej więcej co 64k w moim systemie.

Powyższe zostało przetestowane na Fedorze 13 x86_64 i wydaje się być w stanie skopiować pliki larg (ish).

1

Od splice(2): Komentarz

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 wskazywały, że otworzył plik w trybie dopisywania.