sendfile - Transfert de données entre descripteurs de fichier
Bibliothèque C standard (
libc,
-lc)
#include <sys/sendfile.h>
ssize_t sendfile(int out_fd, int in_fd, off_t *_Nullable offset,
size_t count);
sendfile() copie des données entre deux descripteurs de fichier.
Comme la copie est assurée à l'intérieur du noyau,
sendfile() est plus efficace que la combinaison
read(2)/
write(2) qui exige le transfert des données entre
l'espace noyau et l'espace utilisateur.
in_fd doit être un descripteur de fichier ouvert en lecture et
out_fd un descripteur ouvert en écriture.
Si
offset n'est pas NULL, c'est un pointeur sur une variable contenant la
tête de lecture (Ndt : file offset) à partir de laquelle
sendfile() commencera la lecture dans
in_fd. Lorsque
sendfile() se termine, la variable est remplie avec la position de
l'octet immédiatement après le dernier octet lu. Si
offset n'est pas NULL,
sendfile() ne modifie pas la position
actuelle dans le fichier
in_fd ; autrement, la position actuelle
de la tête de lecture est ajustée pour refléter le nombre
d'octets lus à partir de
in_fd.
Si
offset est NULL, les données sont lues dans
in_fd
à partir de la position actuelle de la tête de lecture et
celle-ci sera ajustée par l'appel.
L'argument
count est le nombre d'octets à copier entre les
descripteurs de fichiers.
L'argument
in_fd doit correspondre à un fichier prenant en charge
les opérations de type
mmap(2) et ne peut donc pas être
un socket.
Avant Linux 2.6.33,
out_fd doit correspondre à un socket.
Depuis Linux 2.6.33, ce peut être n'importe quel fichier. Si
c'est un fichier normal,
sendfile() modifie la position de tête
de lecture en conséquence.
Si le transfert a réussi, le nombre d'octets écrits dans
out_fd est renvoyé. Remarquez qu'un appel à
sendfile() réussi peut écrire moins d'octets que
demandé, l'appelant doit se préparer à
réitérer l'appel en cas de données non envoyées.
Voir aussi les NOTES.
En cas d'erreur, la valeur de retour est
-1 et
errno est
définie pour préciser l'erreur.
- EAGAIN
- L'écriture est non bloquante (attribut
O_NONBLOCK du descripteur) et l'opération devrait
bloquer.
- EBADF
- Le fichier d'entrée n'est pas ouvert en lecture ou
celui de sortie en écriture.
- EFAULT
- Un pointeur se trouve en dehors de l'espace
d'adressage.
- EINVAL
- Le descripteur n'est pas valable ou est verrouillé,
ou une opération de type mmap(2) n'est pas disponible sur
in_fd, ou bien count est négatif.
- EINVAL
-
out_fd a un drapeau O_APPEND
positionné. Cela n'est actuellement pas géré par
sendfile().
- EIO
- Erreur pendant la lecture depuis in_fd.
- ENOMEM
- Mémoire insuffisante pour lire depuis
in_fd.
- EOVERFLOW
-
count est trop grand, l'opération ferait
dépasser la taille maximale du fichier d'entrée ou de
sortie.
- ESPIPE
-
offset n'est pas NULL mais le fichier
d'entrée n'est pas adressable.
sendfile() est une nouveauté de Linux 2.2. Le fichier
d'en-tête
<sys/sendfile.h> est présent depuis la
glibc 2.1.
Pas spécifié dans POSIX.1-2001, ni dans d'autres normes.
D'autres systèmes UNIX implémentent
sendfile() avec
d'autres sémantiques, et d'autres prototypes. Il ne faut pas l'utiliser
dans un programme portable.
sendfile() transfèrera un maximum de 0x7ffff000
(2 147 479 552) octets et renvoie le nombre d'octets
transférés (cela est vrai tant pour des systèmes
32 bits que 64 bits).
Si vous voulez utiliser
sendfile() pour envoyer un fichier au travers
d'un socket TCP, tout en le précédant de données
d'en-tête, voyez l'option
TCP_CORK de
tcp(7) pour
minimiser le nombre de paquets, et optimiser les performances.
Sous Linux 2.4 et précédents,
out_fd pouvait aussi
correspondre à un fichier ordinaire, cette possibilité a disparu
dans la série 2.6.3 du noyau Linux, puis rétablie dans
Linux 2.6.33.
L'appel système original de Linux
sendfile() ne permettait pas de
gérer les positions dans les gros fichiers. En conséquence,
Linux 2.4 a ajouté
sendfile64(), avec un type
élargi pour le paramètre
offset. La fonction
sendfile() de la glibc qui l'encapsule gère de manière
transparente ces différences entre noyaux.
Les applications peuvent se rabattre sur
read(2) et
write(2) au
cas où
sendfile() échoue avec
EINVAL ou
ENOSYS.
Si
out_fd renvoie à un socket ou un tube qui ne gère pas la
copie, les appelants doivent s'assurer que les parties
transférées du fichier auquel renvoie
in_fd ne soient pas
modifiées jusqu'à ce que le lecteur de l'autre
côté de
out_fd n'ait consommé les données
transférées.
L'appel
splice(2) spécifique à Linux gère le
transfert de données entre des descripteurs de fichiers arbitraires,
pourvu que l'un d'eux (ou les deux) soit un tube.
copy_file_range(2),
mmap(2),
open(2),
socket(2),
splice(2)
La traduction française de cette page de manuel a été
créée par Christophe Blaess
<
https://www.blaess.fr/christophe/>, Stéphan Rafin
<
[email protected]>, Thierry Vignaud
<
[email protected]>, François Micaux, Alain Portal
<
[email protected]>, Jean-Philippe Guérard
<
[email protected]>, Jean-Luc Coulon (f5ibh)
<
[email protected]>, Julien Cristau
<
[email protected]>, Thomas Huriaux <
[email protected]>,
Nicolas François <
[email protected]>, Florentin
Duneau <
[email protected]>, Simon Paillard
<
[email protected]>, Denis Barbier
<
[email protected]>, David Prévot <
[email protected]> et
Jean-Philippe MENGUAL <
[email protected]>
Cette traduction est une documentation libre ; veuillez vous reporter
à la
GNU
General Public License version 3 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 à
[email protected]