splice(2)

NOM
splice - Copier des données vers/depuis un tube

BIBLIOTHÈQUE
Bibliothèque C standard (libc, -lc)

SYNOPSIS
#define _GNU_SOURCE         /* See feature_test_macros(7) */
#define _FILE_OFFSET_BITS 64
#include <fcntl.h>

ssize_t splice(int fd_in, off_t *_Nullable off_in,
               int fd_out, off_t *_Nullable off_out,
               size_t size, unsigned int flags);

DESCRIPTION
splice() moves data between two file descriptors without copying between kernel address space and user address space. It transfers up to size bytes of data from the file descriptor fd_in to the file descriptor fd_out, where one of the file descriptors must refer to a pipe.

Les sémantiques suivantes s'appliquent à fd_in et off_in :

-   Si fd_in correspond à un tube, alors off_in doit être NULL.

-   Si fd_in ne correspond pas à un tube et si off_in est NULL, alors les octets sont lus depuis in_fd à partir de la position actuelle dans le fichier et la position résultante est mise à jour de façon appropriée.

-   If fd_in does not refer to a pipe and off_in is not NULL, then off_in must point to a buffer which specifies the starting offset from which bytes will be read from fd_in; in this case, the file offset of fd_in is not changed, and the offset pointed to by off_in is adjusted appropriately instead.

Il en va de même pour fd_out et off_out.

L'argument flags est un masque de bits constitué par un OU binaire entre une ou plusieurs des valeurs suivantes :

SPLICE_F_MOVE
    Essayer de déplacer des pages au lieu de les copier. Ceci n'est qu'une astuce pour le au noyau : des pages peuvent quand même être copiées si le noyau ne peut pas déplacer les pages du tube ou si les tampons du tube ne correspondent pas à des pages entières. La première implémentation de cet attribut comportait un bogue : ainsi, à partir de Linux 2.6.21 il ne fait rien (mais est toujours permis dans un appel à splice()) ; dans le futur, une implémentation correcte pourra être restaurée.

SPLICE_F_NONBLOCK
    Ne pas bloquer sur les entrées-sorties. Cela rend les opérations de splice sur le tube non bloquantes, mais splice() peut tout de même bloquer car les descripteurs de fichier sur lesquels il opère peuvent bloquer (sauf s'ils ont l'attribut O_NONBLOCK).

SPLICE_F_MORE
    Des données supplémentaires seront copiées plus tard. C'est une astuce utile lorsque fd_out correspond à un socket (voir aussi la description de MSG_MORE dans send(2) et la description de TCP_CORK dans tcp(7)).

SPLICE_F_GIFT
    N'a pas d'effet pour splice() ; consultez vmsplice(2).

VALEUR RENVOYÉE
S'il réussit, splice() renvoie le nombre d'octets transférés dans ou à partir du tube.

Une valeur de retour de 0 signifie la fin de l'entrée. Si fd_in correspond à un tube, alors cela signifie qu'il n'y avait pas de données à transférer et que cela n'aurait pas de sens de bloquer parce qu'il n'y a pas d'écrivain connecté à l'extrémité d'écriture du tube.

En cas d'erreur, splice() renvoie -1 et errno est positionné pour indiquer la cause de l'erreur.

ERREURS

EAGAIN
    SPLICE_F_NONBLOCK était indiqué dans flags ou un des descripteurs de fichier a été marqué comme non bloquant (O_NONBLOCK), et l'opération pourrait bloquer.

EBADF
    Au moins un des descripteurs de fichier n'est pas valable, ou n'a pas le mode de lecture ou d'écriture approprié.

EINVAL
    Le système de fichiers cible ne prend pas en charge l'opération splice().

EINVAL
    Le fichier cible est ouvert en mode ajout.

EINVAL
    Aucun des descripteurs de fichier ne correspond à un tube.

EINVAL
    Une position a été donnée pour un périphérique non adressable (par exemple un tube).

EINVAL
    fd_in ou fd_out font référence au même tube.

ENOMEM
    Plus assez de mémoire.

ESPIPE
    off_in ou off_out est différent de NULL, mais le descripteur de fichier correspondant pointe vers un tube.

NORMES
Linux.

HISTORIQUE
Linux 2.6.17, glibc 2.5.

Dans Linux 2.6.30 et précédents, précisément un des descripteurs de fichier fd_in ou fd_out était requis d'être un tube. Depuis Linux 2.6.31, les deux arguments peuvent correspondre à des tubes.

NOTES
Les trois appels système splice(), vmsplice(2) et tee(2) fournissent aux programmes utilisateur le contrôle complet d'un tampon arbitraire du noyau, implémenté côté noyau en utilisant le même type de tampons que pour les tubes. Ces appels système assurent les tâches suivantes :

splice()
    déplace des données depuis le tampon vers un descripteur de fichier arbitraire, ou vice versa, ou bien depuis un tampon vers un autre.

tee(2)
    « copie » les données d'un tampon vers un autre.

vmsplice(2)
    « copie » des données de l'espace utilisateur vers le tampon.

Bien qu'il soit question de copie, les vraies copies sont en général évitées. Le noyau implémente en effet le tampon d'un tube comme un ensemble de pointeurs vers des pages de mémoire noyau pouvant être référencées plusieurs fois. Le noyau crée des « copies » des pages dans un tampon en créant de nouveaux pointeurs (pour le tampon de sortie) pointant vers les pages, et en incrémentant les compteurs de références des pages : seuls les pointeurs sont copiés, et pas les pages du tampon.

_FILE_OFFSET_BITS doit être défini à 64 dans du code qui utilise off_in ou off_out différent de NULL, ou qui récupère l'adresse de splice, si le code est destiné à être protable sur des plateformes x86 et ARM 32 bits classiques où la taille par défaut de off_t est de 32 bits.

EXEMPLES
See tee(2) for another example.

    #define _GNU_SOURCE
    #define _FILE_OFFSET_BITS 64
    #include <err.h>
    #include <fcntl.h>
    #include <stdint.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <unistd.h>

    int
    main(void)
    {
            int         fd;
            int         pfd[2];
            off_t       off;
            [[gnu::nonstring]]
    	const char  s[12] = "Hello, world";

            fd = open("out", O_WRONLY | O_CREAT | O_EXCL, 0666);
            if (fd == -1)
                    err(EXIT_FAILURE, "open");

            if (pipe(pfd) == -1)
                    err(EXIT_FAILURE, "pipe");

            if (write(pfd[1], s, sizeof(s)) != sizeof(s))
                    err(EXIT_FAILURE, "write");
            if (close(pfd[1]) == -1)
                    err(EXIT_FAILURE, "close");

            off = 10;
            if (splice(pfd[0], NULL, fd, &off, sizeof(s), 0) != sizeof(s))
                    err(EXIT_FAILURE, "splice");
            if (close(pfd[0]) == -1)
                    err(EXIT_FAILURE, "close");

            printf("New offset is %jd\n", (intmax_t) off);

            if (close(fd) == -1)
                    err(EXIT_FAILURE, "close");
            exit(EXIT_SUCCESS);
    }

VOIR AUSSI
copy_file_range(2), sendfile(2), tee(2), vmsplice(2), pipe(7)

TRADUCTION
La traduction française de cette page de manuel a été créée par Christophe Blaess <https://www.blaess.fr/christophe/>, Stéphan Rafin <stephan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, François Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Guérard <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>, Thomas Huriaux <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis Barbier <barbier@debian.org>, David Prévot <david@tilapin.org> et Jean-Pierre Giraud <jean-pierregiraud@neuf.fr>

Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 (https://www.gnu.org/licenses/gpl-3.0.html) concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.

Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à debian-l10n-french@lists.debian.org.