Pergunta

Aqui está outra pergunta sobre Splice (). Espero usá -lo para copiar arquivos e estou tentando usar duas chamadas de emenda unidas por um tubo, como o exemplo na página da Wikipedia da Splice. Escrevi um caso de teste simples que só tenta ler os primeiros 32k bytes de um arquivo e escrevê -los para outro:

#define _GNU_SOURCE
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

int main(int argc, char **argv) {
    int pipefd[2];
    int result;
    FILE *in_file;
    FILE *out_file;

    result = pipe(pipefd);

    in_file = fopen(argv[1], "rb");
    out_file = fopen(argv[2], "wb");

    result = splice(fileno(in_file), 0, pipefd[1], NULL, 32768, SPLICE_F_MORE | SPLICE_F_MOVE);
    printf("%d\n", result);

    result = splice(pipefd[0], NULL, fileno(out_file), 0, 32768, SPLICE_F_MORE | SPLICE_F_MOVE);
    printf("%d\n", result);

    if (result == -1)
        printf("%d - %s\n", errno, strerror(errno));

    close(pipefd[0]);
    close(pipefd[1]);
    fclose(in_file);
    fclose(out_file);

    return 0;
}

Quando eu executo isso, o arquivo de entrada parece ser lido corretamente, mas a segunda chamada de emenda falha com o EINVAL. Alguém sabe o que estou fazendo de errado aqui?

Obrigado!

Foi útil?

Solução

Que tipo de sistema (s) de arquivos você está copiando para/de?

Seu exemplo é executado no meu sistema quando os dois arquivos estão no Ext3, mas falha quando uso uma unidade externa (esqueço de maneira insuficiente se for DOS ou NTFS). Meu palpite é que um ou ambos os seus arquivos estão em um sistema de arquivos que a emenda não suporta.

Outras dicas

De MANPAGEM DE ENTREGA:

   EINVAL Target  file  system  doesn't  support  splicing; target file is
          opened in append mode; neither of the descriptors  refers  to  a
          pipe; or offset given for non-seekable device.

Sabemos que um dos descritores é um tubo e o arquivo não está aberto no modo Apênd. Também sabemos que nenhum deslocamento é dado (0 é equivalente a NULL - Você quis passar um ponteiro para um deslocamento zero?), Então esse não é o problema. Portanto, o sistema de arquivos que você está usando não suporta splicing nos arquivos.

o splice(2) Chamada do sistema é para copiar entre arquivos e tubos e não entre arquivos, portanto, não pode ser usado para copiar entre arquivos, como foi apontado pelas outras respostas.

A partir do Linux 4.5, no entanto, um novo copy_file_range(2) Chamada do sistema está disponível que pode copiar entre arquivos. No caso do NFS, ele pode até causar cópia do lado do servidor.

A página do Man Linked contém um programa de exemplo completo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top