Question

Je suis en train de tester l'appel système sendfile() sous Linux 2.6.32 aux données zéro copie entre deux fichiers réguliers. Pour autant que je comprends, cela devrait fonctionner. Depuis 2.6.22, sendfile() a été mis en œuvre en utilisant splice(), et à la fois le fichier d'entrée et le fichier de sortie peuvent être soit des fichiers réguliers ou prises

Ce qui suit est le contenu de 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;
}

Et quand je suis en cours d'exécution les commandes suivantes:

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

La sortie est

sendfile: Invalid argument

Et lors de l'exécution

$ strace ./a.out infile outfile

La sortie contient

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

Qu'est-ce que je fais mal?

Était-ce utile?

La solution

Vous avez oublié de vérifier que argc est égal à 3, à savoir que vous ouvrez le fichier de sortie par le nom argv[2] mais seulement donner votre programme un argument (et vous n'êtes pas la vérification des erreurs après open(2).)

Vous pouvez utiliser strace(1) pour savoir qui échoue appel système.

Edit:

Ce noyau ressemble plus à moi. Même source (modulo vérification d'erreur) fonctionne très bien ici sous 2.6.33.4 #3 SMP. En outre, une raison particulière que vous copiez juste un octet?

#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 );
}

Trace:

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$
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top