rename, renameat, renameat2 - Changer le nom ou l'emplacement d'un
fichier
Bibliothèque C standard (libc, -lc)
#include <stdio.h>
int rename(const char *oldpath, const char *newpath);
#include <fcntl.h> /* Définition des constantes AT_* */
#include <stdio.h>
int renameat(int olddirfd, const char *oldpath,
int newdirfd, const char *newpath);
int renameat2(int olddirfd, const char *oldpath,
int newdirfd, const char *newpath, unsigned int flags);
renameat():
Depuis la 2.10:
_POSIX_C_SOURCE >= 200809L
Avant la glibc 2.10:
_ATFILE_SOURCE
renameat2():
_GNU_SOURCE
rename() renomme un fichier, en le déplaçant
dans un autre répertoire si nécessaire. Tous les autres liens
physiques vers le fichier (comme créés avec link(2))
sont inchangés. Les descripteurs de fichier ouverts sur
oldpath ne sont pas non plus affectés.
Diverses restrictions déterminent si
l’opération de renommage a réussie. Consulter le
paragraphe ERREURS ci-après.
Si newpath existe déjà, il sera
remplacé de manière atomique, de manière à ce
qu'à aucun moment, un autre processus tentant d'accéder
à newpath ne le voie absent. Cependant, il existera
probablement un créneau pendant lequel oldpath et
newpath se référeront au fichier en cours de
renommage.
Si oldpath et newpath sont des liens physiques
existants correspondant au même fichier, rename() ne fait rien
et renvoie un code de succès.
Si newpath existe mais que l'opération échoue
pour une raison quelconque, rename() garantit la présence
d'une instance de newpath en place.
oldpath peut être un répertoire. Dans ce cas,
newpath doit être soit absent, soit un répertoire
vide.
Si oldpath correspond à un lien symbolique, le lien
est renommé ; si newpath correspond à un lien
symbolique, le lien est écrasé.
L'appel système renameat() fonctionne exactement
comme rename(), les seules différences étant
décrites ici.
Si le chemin donné dans oldpath est relatif, il est
interprété par rapport au répertoire
référencé par le descripteur de fichier olddirfd
(plutôt que par rapport au répertoire de travail du processus,
comme c'est le cas pour rename()).
Si oldpath est un chemin relatif, et si olddirfd a
la valeur spéciale AT_FDCWD, alors oldpath est
interprété par rapport au répertoire de travail du
processus (comme pour rename()).
Si oldpath est un chemin absolu, olddirfd est
ignoré.
L'interprétation de newpath est identique à
celle de oldpath, excepté qu'un chemin relatif est
interprété par rapport au répertoire correspondant
à newdirfd.
Consultez openat(2) pour une explication de la
nécessité de renameat().
renameat2() possède un argument additionnel,
flags. Un appel à renameat2() sans passer de valeur
à l'argument flags équivaut à un appel à
renameat().
L'argument flags est un masque de bits
éventuellement vide ou contenant un ou plusieurs des attributs
suivants :
- RENAME_EXCHANGE
- Échange oldpath et newpath par une opération
atomique. Les deux chemins doivent exister mais peuvent être de
différentes natures (par exemple, l'un peut être un
répertoire non vide et l'autre un lien symbolique).
- RENAME_NOREPLACE
- Ne pas écraser newpath lors du renommage. Renvoi
d’une erreur si newpath existe déjà.
- RENAME_NOREPLACE ne peut être employer en même temps
que RENAME_EXCHANGE.
- RENAME_NOREPLACE nécessite une prise en charge par le
système de fichiers sous-jacent. Cette prise en charge pour divers
systèmes de fichiers a été ajoutée comme
suit :
- •
- ext4 (Linux 3.15) ;
- •
- btrfs, tmpfs et cifs (Linux 3.17) ;
- •
- xfs (Linux 4.0) ;
- •
- la prise en charge par plusieurs autres systèmes de fichiers a
été ajoutée dans Linux 4.9, dont ext2, minix,
reiserfs, jfs, vfat et bpf.
- RENAME_WHITEOUT
(depuis Linux 3.18)
- Cette opération n’a de sens que pour les
implémentations de système de fichiers overlay/union.
- L’indication de RENAME_WHITEOUT crée un objet de
« whiteout » (simulation d’effacement)
à la source du renommage en même temps que la
réalisation de ce renommage. Toute l’opération est
atomique, de telle façon que si le renommage réussit, alors
le whiteout est aussi créé.
- Un « whiteout » est un objet de signification
spéciale dans les constructions de système de fichiers
union/overlay. Dans ces constructions, plusieurs couches existent et seule
la plus haute est toujours modifiée. Un whiteout sur la couche
supérieure cachera de fait un fichier apparié dans la couche
inférieure, donnant l’impression que le fichier
n’existe pas.
- Lorsqu’un fichier existant dans la couche inférieure est
renommé, le fichier est d’abord copié au niveau
supérieur (s’il n’existe pas déjà sur
ce niveau) puis est renommé sur la couche en
lecture-écriture supérieure. Au même moment, le
fichier source doit être mis
« whiteout » (de façon que la version
dans la couche inférieure soit rendue invisible). Toute
l’opération doit être réalisée de
manière atomique.
- Lorsqu’il ne fait pas partie d’une union/overlay, le
whiteout apparaît comme un périphérique
caractère avec un numéro de périphérique. (Il
est à remarquer que les implémentations union/overlay
peuvent employer des méthodes différentes pour stocker les
entrées whiteout. Précisément, les unions de montage
BSD utilisent un type d’inode distinct, DT_WHT, lesquels,
tout en étant gérés par certains systèmes de
fichiers disponibles dans Linux, tels que CODA et XFS, sont ignorés
par le code de prise en charge du noyau pour whiteout, comme pour au
moins, Linux 4.19.)
- RENAME_WHITEOUT nécessite les mêmes droits que pour
la création d’un nœud de périphérique
(c'est-à-dire, la capacité CAP_MKNOD).
- RENAME_WHITEOUT ne peut être employé en même
temps que RENAME_EXCHANGE.
- RENAME_WHITEOUT nécessite une prise en charge par le
système de fichiers sous-jacent. Entre autres les systèmes
de fichiers tmpfs (depuis Linux 3.18), ext4 (depuis
Linux 3.18), XFS (depuis Linux 4.1), f2fs (depuis
Linux 4.2), btrfs (depuis Linux 4.7) et ubifs (depuis
Linux 4.9) le prennent en charge.
En cas de succès, zéro est renvoyé. En cas
d'erreur, -1 est renvoyé et errno est définie
pour préciser l'erreur.
- EACCES
- La permission d'écrire est refusée dans le répertoire
contenant oldpath ou newpath, ou la permission de parcours
est refusée pour l'un des répertoires dans le chemin
d’accès à oldpath ou newpath, ou encore
oldpath est un répertoire et ne permet pas l'écriture
(nécessaire pour mettre à jour l'entrée ..).
(Consultez aussi path_resolution(7).)
- EBUSY
- Le renommage a échoué car oldpath ou newpath
est un répertoire utilisé par un processus (peut-être
comme répertoire de travail, ou comme répertoire racine, ou
ouvert en lecture), ou il est utilisé par le système (comme
point de montage par exemple). Le système a donc
considéré qu'il y avait une erreur. (Notez qu'il n'est pas
indispensable de renvoyer EBUSY dans un tel cas
— rien n'empêche d'effectuer le renommage
malgré tout — mais il est permis de retourner
EBUSY si le système n'arrive pas à gérer une
telle situation).
- EDQUOT
- Le quota de blocs de disque de l'utilisateur sur le système de
fichiers a été atteint.
- EFAULT
- oldpath ou newpath pointent en dehors de l'espace
d'adressage accessible.
- EINVAL
- Le nouveau chemin contient un préfixe de chemin de l’ancien,
ou plus généralement, un répertoire ne peut pas
être déplacé dans ses propres
sous-répertoires.
- EISDIR
- newpath est un répertoire existant mais oldpath n'est
pas un répertoire
- ELOOP
- Trop de liens symboliques ont été rencontrés en
parcourant oldpath ou newpath.
- EMLINK
- oldpath a déjà un nombre maximal de liens, ou bien
c'est un répertoire, et le répertoire contenant
newpath a le nombre maximal de liens.
- ENAMETOOLONG
- oldpath ou newpath est trop long.
- ENOENT
- Le lien indiqué par oldpath n'existe pas, ou bien un
répertoire du chemin newpath n'existe pas, ou bien
oldpath ou newpath est une chaîne vide.
- ENOMEM
- La mémoire disponible du noyau n'était pas suffisante.
- ENOSPC
- Le périphérique contenant le fichier n'a pas de place pour
une nouvelle entrée de répertoire.
- ENOTDIR
- Un élément utilisé comme répertoire dans
oldpath ou newpath n'est pas un répertoire, ou bien
oldpath est un répertoire et newpath existe mais
n'est pas un répertoire.
- ENOTEMPTY ou
EEXIST
- newpath est un répertoire non vide (contient autre chose que
« . » et
« .. »).
- EPERM ou
EACCES
- Le répertoire contenant oldpath a le sticky bit
(S_ISVTX) positionné, et l'UID effectif du processus n'est
ni celui de l’UID du fichier à déplacer, ni celui du
répertoire le contenant, et le processus n'est pas
privilégié (sous Linux : n'a pas la capacité
CAP_FOWNER ; ou newpath est un fichier existant et le
répertoire le contenant a son sticky bit positionné et l'UID
effectif du processus n'est ni celui du fichier à déplacer,
ni celui du répertoire le contenant, et le processus n'est pas
privilégié (sous Linux : n'a pas la capacité
CAP_FOWNER ; ou alors le système de fichiers
contenant oldpath ne permet pas le renommage du type
demandé.
- EROFS
- Le fichier se trouve sur un système de fichiers en lecture
seule.
- EXDEV
- oldpath et newpath ne sont pas sur le même
système de fichiers monté. (Linux permet de monter un
système de fichiers à plusieurs endroits, mais
rename() ne fonctionne pas à travers des points de montage
différents, même si le système de fichiers est
monté sur les deux.)
Les erreurs supplémentaires suivantes peuvent
également se produire pour renameat() et
renameat2() :
- EBADF
- oldpath (newpath) est relatif, mais olddirfd
(newdirfd n'est pas un descripteur de fichier valable.
- ENOTDIR
- oldpath est un chemin relatif, et olddirfd est un
descripteur de fichier ne référençant pas un
répertoire ; ou bien c'est le cas pour newpath et
newdirfd.
Les erreurs supplémentaires suivantes peuvent
également se produire pour renameat2() :
- EEXIST
- flags contient l'attribut RENAME_NOREPLACE et newpath
existe déjà.
- EINVAL
- flags contient un drapeau non valable.
- EINVAL
- RENAME_NOREPLACE et RENAME_EXCHANGE sont tous les deux
indiqués dans flags.
- EINVAL
- RENAME_WHITEOUT et RENAME_EXCHANGE sont tous les deux
indiqués dans flags.
- EINVAL
- Le système de fichiers ne prend pas en charge l'un des attributs de
flags.
- ENOENT
- flags contient RENAME_EXCHANGE et newpath n'existe
pas.
- EPERM
- RENAME_WHITEOUT est indiqué dans flags mais
l'appelant n'a pas la capacité CAP_MKNOD.
renameat() a été ajouté dans
Linux 2.6.16 ; la prise en charge de la bibliothèque a
été ajoutée dans la glibc 2.4.
renameat2() a été ajouté dans
Linux 3.15 ; la prise en charge de la bibliothèque a
été ajoutée dans la glibc 2.28.
rename() : 4.3BSD, C99, POSIX.1-2001,
POSIX.1-2008.
renameat() : POSIX.1-2008.
renameat2() est spécifique à Linux.
Dans les anciens noyaux où renameat() n’est
pas disponible, les fonctions d’enveloppe de la glibc renvoient
à l’utilisation de rename(). Quand oldpath et
newpath sont des noms de chemin relatif, la glibc construit les noms
de chemin basés sur les liens symboliques dans /proc/self/fd
qui correspondent aux arguments olddirfd et newdirfd.
Sur les systèmes de fichiers NFS, ce n'est pas parce que
l'opération a échoué que le fichier n'a pas
été renommé. Si le serveur effectue le renommage et se
plante, la RPC transmise qui sera traitée lorsque le serveur sera
à nouveau en état va entrainer un échec. L'application
doit gérer ce genre de problème. Consultez link(2) pour
un problème similaire.
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>,
Frédéric Hantrais <fhantrais@gmail.com> et Jean-Paul
Guillonneau <guillonneau.jeanpaul@free.fr>
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.