NOM

rename, renameat, renameat2 - Changer le nom ou l'emplacement d'un fichier

BIBLIOTHÈQUE

Bibliothèque C standard ( libc, -lc)

SYNOPSIS

#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);
Exigences de macros de test de fonctionnalités pour la glibc (consulter feature_test_macros(7)) :
renameat():
    Depuis la 2.10:
        _POSIX_C_SOURCE >= 200809L
    Avant la glibc 2.10:
        _ATFILE_SOURCE
renameat2():
    _GNU_SOURCE

DESCRIPTION

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é.

renameat()

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()

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.

VALEUR RENVOYÉE

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.

ERREURS

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.

VERSIONS

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.

STANDARDS

rename() : 4.3BSD, C99, POSIX.1-2001, POSIX.1-2008.
renameat() : POSIX.1-2008.
renameat2() est spécifique à Linux.

NOTES

Notes de la glibc

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.

BOGUES

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.

VOIR AUSSI

mv(1), rename(1), chmod(2), link(2), symlink(2), unlink(2), path_resolution(7), symlink(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 <[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]>, Frédéric Hantrais <[email protected]> et Jean-Paul Guillonneau <[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]