Domanda

Ecco un'altra domanda su splice (). Spero di usarlo per copiare i file, e sto cercando di utilizzare due chiamate di splicing uniti da un tubo di come l'esempio sulla pagina di Wikipedia di giunzione. Ho scritto un semplice banco di prova, che cerca solo di leggere i primi 32K byte da un file e scriverli ad un altro:

#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 eseguo questo, il file di input sembra essere letto correttamente, ma la seconda chiamata giunzione non riesce con EINVAL. Qualcuno sa che cosa sto facendo male qui?

Grazie!

È stato utile?

Soluzione

Che tipo di file system (s) stai copiando da /?

Il vostro esempio viene eseguito sul mio sistema, quando entrambi i file sono in ext3, ma fallisce quando uso un disco esterno (non ricordo estemporaneo se è DOS o NTFS). La mia ipotesi è che uno o entrambi i vostri file sono su un file system che giunzione non supporta.

Altri suggerimenti

giunzione pagina man :

   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.

Sappiamo che uno dei descrittori è un tubo, e il file non è aperto in modalità di accodamento. Sappiamo anche non si specifica un offset (0 è equivalente a NULL - Intendi passare in un puntatore a uno spostamento di origine?), In modo che non è questo il problema. Pertanto, il file system che si sta utilizzando non supporta splicing ai file.

Il splice(2) chiamata di sistema è per la copia tra i file e le tubi e non tra i file, in modo da non può essere usato per copiare tra i file, come è stato sottolineato da altri risposte.

A partire da Linux 4.5 comunque un nuovo copy_file_range(2) chiamata di sistema è disponibile che può copiare tra i file. Nel caso di NFS può anche causare la copia lato server.

La pagina man collegata contiene un programma completo esempio.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top