table of contents
COPY_FILE_RANGE(2) | Manuel du programmeur Linux | COPY_FILE_RANGE(2) |
NOM¶
copy_file_range - Copier une plage de données d'un fichier vers un autre
SYNOPSIS¶
#define _GNU_SOURCE #include <unistd.h>
ssize_t copy_file_range(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags);
DESCRIPTION¶
L'appel système copy_file_range() effectue une copie interne au noyau entre deux descripteurs de fichier sans devoir en plus transférer des données du noyau à l'espace utilisateur puis revenir au noyau. Jusqu'à len octets de données sont transférés du descripteur de fichier source fd_in au descripteur de fichier cible fd_out, écrasant toute donnée se trouvant dans la plage du fichier cible sollicité.
La sémantique suivante s'applique à off_in et des déclarations identiques s'appliquent à off_out :
- Si off_in est NULL, les octets sont lus dans fd_in à partir de la position du fichier, laquelle est ajustée par le nombre d'octets copiés.
- Si off_in n'est pas NULL, off_in doit pointer vers un tampon qui indique le point de départ à partir duquel les octets de fd_in seront lus. La position du fichier de fd_in n'est pas modifiée mais off_in est ajusté correctement.
L'argument flags n'est fourni que pour des extensions futures et doit être positionné à 0 pour l'instant.
VALEUR RENVOYÉE¶
En cas de succès, copy_file_range() renverra le nombre d'octets copiés entre les fichiers. Il pourrait être inférieur à la taille demandée au départ.
En cas d'erreur, copy_file_range() renvoie -1 et errno est configuré pour indiquer l'erreur.
ERREURS¶
- EBADF
- Un ou plusieurs descripteurs de fichier ne sont pas valables, ou fd_in n'est pas ouvert en lecture, ou bien fd_out n'est pas ouvert en écriture, ou bien le drapeau O_APPEND est positionné pour un descripteur de fichier auquel se rapporte fd_out.
- EFBIG
- Tentative d'écriture d'une plage dépassant la taille maximale d'un fichier définie par l'implémentation ou la limite de taille de fichier du processus, ou bien sur une position au-delà de celle maximum autorisée.
- EINVAL
- La plage demandée dépasse la fin du fichier source ou le paramètre flags ne vaut pas 0.
- EIO
- Une erreur E/S de bas niveau s'est produite lors de la copie.
- EISDIR
- fd_in ou fd_out se rapporte à un répertoire.
- ENOMEM
- Plus assez de mémoire.
- ENOSPC
- Il n'y a pas assez d'espace sur le système de fichiers cible pour terminer la copie.
- EXDEV
- Les fichiers auxquels se rapportent file_in et file_out ne sont pas sur le même système de fichiers monté.
VERSIONS¶
L'appel système copy_file_range() est apparu pour la première fois dans Linux 4.5, mais la glibc 2.27 offre une émulation dans l'espace utilisateur s'il n'est pas disponible.
CONFORMITɶ
L'appel système copy_file_range() est une extension GNU et un non standard de Linux.
NOTES¶
Si file_in est un fichier éparpillé, il se peut que copy_file_range() agrandisse les trous existant dans la plage demandée. Les utilisateurs peuvent tirer avantage de profiter d'un appel à copy_file_range() dans une boucle et en utilisant les opérations SEEK_DATA et SEEK_HOLE de lseek(2) pour chercher des emplacements de segments de données.
copy_file_range() donne aux systèmes de fichiers la possibilité d'implémenter des techniques de « copie accélérée » telles que l'utilisation de reflink (c'est-à-dire deux ou plusieurs i-nœuds partageant des pointeurs avec les mêmes blocs de disque copy-on-write) ou server-side-copy (dans le cas de NFS).
EXEMPLE¶
#define _GNU_SOURCE #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <sys/stat.h> #include <sys/syscall.h> #include <unistd.h> /* Sur les versions de la glibc antérieures à 2.27, il faut
appeler copy_file_range() en utilisant syscall(2) */ static loff_t copy_file_range(int fd_in, loff_t *off_in, int fd_out,
loff_t *off_out, size_t len, unsigned int flags) {
return syscall(__NR_copy_file_range, fd_in, off_in, fd_out,
off_out, len, flags); } int main(int argc, char **argv) {
int fd_in, fd_out;
struct stat stat;
loff_t len, ret;
if (argc != 3) {
fprintf(stderr, "Utilisation : %s <source> <destination>\n", argv[0]);
exit(EXIT_FAILURE);
}
fd_in = open(argv[1], O_RDONLY);
if (fd_in == -1) {
perror("open (argv[1])");
exit(EXIT_FAILURE);
}
if (fstat(fd_in, &stat) == -1) {
perror("fstat");
exit(EXIT_FAILURE);
}
len = stat.st_size;
fd_out = open(argv[2], O_CREAT | O_WRONLY | O_TRUNC, 0644);
if (fd_out == -1) {
perror("open (argv[2])");
exit(EXIT_FAILURE);
}
do {
ret = copy_file_range(fd_in, NULL, fd_out, NULL, len, 0);
if (ret == -1) {
perror("copy_file_range");
exit(EXIT_FAILURE);
}
len -= ret;
} while (len > 0);
close(fd_in);
close(fd_out);
exit(EXIT_SUCCESS); }
VOIR AUSSI¶
COLOPHON¶
Cette page fait partie de la publication 4.16 du projet man-pages Linux. Une description du projet et des instructions pour signaler des anomalies et la dernière version de cette page peuvent être trouvées à l'adresse https://www.kernel.org/doc/man-pages/.
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-Philippe MENGUAL <jpmengual@debian.org>
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 à debian-l10n-french@lists.debian.org.
2 février 2018 | Linux |