readlinkat(2) Lire le contenu d'un lien symbolique

Other Alias

readlink

SYNOPSIS

#include <unistd.h>


ssize_t readlink(const char *pathname, char *buf, size_t bufsiz);

#include <fcntl.h> /* Définition des constantes AT_* */
#include <unistd.h>

int readlinkat(int dirfd, const char *pathname,
char *buf, size_t bufsiz);

Exigences de macros de test de fonctionnalités pour la glibc (consultez feature_test_macros(7)) :

readlinkat() :

_BSD_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED || _POSIX_C_SOURCE >= 200112L

readlinkat():

Depuis la glibc 2.10 :
_XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L
Avant la glibc 2.10 :
_ATFILE_SOURCE

DESCRIPTION

readlink() place le contenu du lien symbolique pathname dans le tampon buf, dont la taille est bufsiz. readlink() n'ajoute pas de caractère NUL dans le tampon buf. Il tronquera le contenu (à la longueur bufsiz) si le tampon est trop petit pour recevoir les données.

readlinkat()

L'appel système readlinkat() fonctionne exactement comme readlink(), les seules différences étant décrites ici.

Si pathname est un chemin relatif, il est interprété par rapport au répertoire référencé par le descripteur de fichier dirfd (plutôt que par rapport au répertoire courant du processus appelant, comme cela est fait par readlink() pour un chemin relatif).

Si pathname est relatif et si dirfd a la valeur spéciale AT_FDCWD, alors pathname est interprété relativement au répertoire de travail du processus appelant, comme pour readlink().

Si pathname est un chemin absolu, dirfd est ignoré.

Depuis Linux 2.6.39, pathname peut être une chaîne vide, auquel cas l'appel opère sur le fichier référencé par dirfd (qui peut avoir été obtenu par open(2) avec le drapeau O_PATH). DAns ce cas, dirfd peut référer à tout type de fichier, pas uniquement un répertoire.

Consultez openat(2) pour une explication de la nécessité de readlinkat().

VALEUR RENVOYÉE

S'il réussit, ces appels renvoient le nombre d'octets placés dans buf. S'il échoue, il renvoie -1 et écrit errno en conséquence.

ERREURS

EACCES
Un élément du chemin d'accès ne permet pas la recherche. (Consultez aussi path_resolution(7).)
EFAULT
buf pointe en dehors de l'espace d'adressage accessible.
EINVAL
bufsiz n'est pas positif.
EINVAL
Le fichier n'est pas un lien symbolique.
EIO
Une erreur d'entrée-sortie est survenue lors de la lecture sur le système de fichiers.
ELOOP
Trop de liens symboliques ont été rencontrés en parcourant le chemin.
ENAMETOOLONG
path ou l'un des composants de ce chemin d'accès est trop long.
ENOENT
Le fichier indiqué n'existe pas.
ENOMEM
Pas assez de mémoire pour le noyau.
ENOTDIR
Un élément du chemin d'accès n'est pas un répertoire.

Les erreurs supplémentaires suivantes peuvent également se produire pour readlinkat() :

EBADF
dirfd n'est pas un descripteur de fichier valable.
ENOTDIR
pathname est relatif, et le descripteur de fichier dirfd est associé à un fichier, pas à un répertoire.

VERSIONS

readlinkat() a été ajouté au noyau Linux dans sa version 2.6.16 ; la glibc le gère depuis la version 2.4.

CONFORMITÉ

readlink() : BSD 4.4 (readlink() est apparue pour la première fois dans BSD 4.2), POSIX.1-2001, POSIX.1-2008.

readlinkat() : POSIX.1-2008.

NOTES

Dans les versions de glibc jusqu'à 2.4 incluse, le type de retour de readlink() était déclaré comme int. À présent, le type de retour est déclaré comme ssize_t, ainsi que le prescrit POSIX.1-2001.

L'utilisation d'un tampon de taille statique risque de ne pas fournir assez de place pour le contenu du lien symbolique. La taille nécessaire au tampon peut être lue dans la valeur stat.st_size renvoyée par un appel à lstat(2) sur le lien. Cependant, le nombre d'octets écrits par readlink() et par readlinkat() devrait être vérifié pour s'assurer que la taille du lien symbolique n'a pas augmenté entre les appels. L'allocation dynamique du tampon pour readlink() et pour readlinkat() résout aussi un problème habituel de portabilité si PATH_MAX est utilisé comme taille de tampon, car la définition de cette constante n'est pas garantie par POSIX si le système n'a pas ce genre de limite.

EXEMPLE

Le programme suivant alloue le tampon nécessaire à readlink() dynamiquement à partir des données fournies par lstat(), en s'assurant qu'il n'y a pas de situation de compétition entre les appels.
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int
main(int argc, char *argv[])
{
    struct stat sb;
    char *linkname;
    ssize_t r;
    if (argc != 2) {
        fprintf(stderr, "Utilisation : %s <chemin>\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    if (lstat(argv[1], &sb) == -1) {
        perror("lstat");
        exit(EXIT_FAILURE);
    }
    linkname = malloc(sb.st_size + 1);
    if (linkname == NULL) {
        fprintf(stderr, "mémoire insuffisante\n");
        exit(EXIT_FAILURE);
    }
    r = readlink(argv[1], linkname, sb.st_size + 1);
    if (r == -1) {
        perror("readlink");
        exit(EXIT_FAILURE);
    }
    if (r > sb.st_size) {
        fprintf(stderr, "la taille du lien symbolique a augmenté"
                        "entre lstat() et readlink()\n");
        exit(EXIT_FAILURE);
    }
    linkname[r] = '\0';
    printf("« %s » pointe vers « %s »\n", argv[1], linkname);
    exit(EXIT_SUCCESS);
}

COLOPHON

Cette page fait partie de la publication 3.65 du projet man-pages Linux. Une description du projet et des instructions pour signaler des anomalies peuvent être trouvées à l'adresse http://www.kernel.org/doc/man-pages/.

TRADUCTION

Depuis 2010, cette traduction est maintenue à l'aide de l'outil po4a <http://po4a.alioth.debian.org/> par l'équipe de traduction francophone au sein du projet perkamon <http://perkamon.alioth.debian.org/>.

Christophe Blaess <http://www.blaess.fr/christophe/> (1996-2003), Alain Portal <http://manpagesfr.free.fr/> (2003-2006). Julien Cristau et l'équipe francophone de traduction de Debian (2006-2009).

Veuillez signaler toute erreur de traduction en écrivant à <[email protected]> ou par un rapport de bogue sur le paquet manpages-fr.

Vous pouvez toujours avoir accès à la version anglaise de ce document en utilisant la commande « man -L C <section> <page_de_man> ».