READLINK(2)

NOM
readlink, readlinkat - Lire le contenu d'un lien symbolique

SYNOPSIS
#include <unistd.h>

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

#include <fcntl.h>            /* Definition of AT_* constants */
#include <unistd.h>

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

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

readlink():
    _XOPEN_SOURCE >= 500 || _POSIX_C_SOURCE >= 200112L
        || /* Glibc <= 2.19 : */ _BSD_SOURCE

readlinkat():
    Depuis la glibc 2.10 :
        _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 d’octet NULL final dans le tampon buf. Il tronquera (silencieusement) le contenu (à la longueur bufsiz) si le tampon est trop petit pour recevoir tout le contenu.

  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 absolu, alors dirfd est ignoré.

Depuis Linux 2.6.39, pathname peut être une chaîne vide, auquel cas l'appel opère sur le lien symbolique référencé par dirfd (qui peut avoir été obtenu par open(2) avec les drapeaux O_PATH et O_NOFOLLOW).

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 (si la valeur renvoyée est égale à bufsiz, il se peut qu'il y ait eu une troncature). S'il échoue, il renvoie -1 et écrit errno pour indiquer l'erreur.

ERREURS

EACCES
    Un élément du chemin d'accès ne permet pas la recherche. (Consultez aussi path_resolution(7).)

EBADF
    (readlinkat()) pathname is relative but dirfd is neither AT_FDCWD nor a valid file descriptor.

EFAULT
    buf pointe en dehors de l'espace d'adressage accessible.

EINVAL
    bufsiz n'est pas un nombre positif.

EINVAL
    Le fichier nommé (à savoir le composant final du nom de fichier dans pathname) 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
    Un nom de chemin d'accès ou l'un des composants d'un nom de chemin d'accès est trop long.

ENOENT
    Le fichier indiqué n'existe pas.

ENOMEM
    La mémoire disponible du noyau n'était pas suffisante.

ENOTDIR
    Un élément du chemin d'accès n'est pas un répertoire.

ENOTDIR
    (readlinkat()) pathname is relative and dirfd is a file descriptor referring to a file other than a directory.

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() : 4.4BSD (readlink() est apparue pour la première fois dans 4.2BSD), POSIX.1-2001, POSIX.1-2008.

readlinkat(): POSIX.1-2008.

NOTES
Dans les versions de la glibc jusqu'à la 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 selon les POSIX si le système n'a pas ce genre de limite.

  Notes de la glibc
Sur les anciens noyaux où readlinkat() n'était pas disponible, la fonction enveloppe de la glibc se rabat sur l'utilisation de readlink(). Quand pathname est un chemin relatif, la glibc construit un chemin à partir du lien symbolique dans /proc/self/fd correspondant au paramètre dirfd.

EXEMPLES
Le programme suivant alloue le tampon nécessaire à readlink() dynamiquement à partir des données fournies par lstat(), en se rabattant sur un tampon de taille PATH_MAX si lstat(2) signale une taille de zéro.

    #include <sys/types.h>
    #include <sys/stat.h>
    #include <limits.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    int
    main(int argc, char *argv[])
    {
        struct stat sb;
        char *buf;
        ssize_t nbytes, bufsiz;
        if (argc != 2) {
            fprintf(stderr, "Usage: %s <pathname>\n", argv[0]);
            exit(EXIT_FAILURE);
        }
        if (lstat(argv[1], &sb) == -1) {
            perror("lstat");
            exit(EXIT_FAILURE);
        }
        /* Ajouter un à la taille du lien, pour pouvoir déterminer si le tampon
           renvoyé par readlink() a été tronqué. */
        bufsiz = sb.st_size + 1;
        /* Certains liens symboliques magiques dans (par exemple) /proc et /sys
           indiquent 'st_size' comme zéro. Dans ce cas, prendre PATH_MAX
           comme estimation « acceptable ». */
        if (sb.st_size == 0)
            bufsiz = PATH_MAX;
        buf = malloc(bufsiz);
        if (buf == NULL) {
            perror("malloc");
            exit(EXIT_FAILURE);
        }
        nbytes = readlink(argv[1], buf, bufsiz);
        if (nbytes == -1) {
            perror("readlink");
            exit(EXIT_FAILURE);
        }
        /* N'afficher que 'nboctets' de 'buf', car il ne contient
           pas d'octet NULL final ('\0'). */
        printf("'%s' pointe vers '%.*s'\n", argv[1], (int) nbytes, buf);
        /* Si la valeur renvoyée était égale à la taille du tampon, la cible du
           lien était plus grande que prévu (peut-être parce que la cible
           a changé entre l'appel à lstat() et l'appel à readlink()).
           Avertir l'utilisateur que la cible renvoyée peut avoir
           été tronquée. */
        if (nbytes == bufsiz)
            printf("(Il se peut que le tampon renvoyé ait été tronqué)\n");
        free(buf);
        exit(EXIT_SUCCESS);
    }

VOIR AUSSI
readlink(1), lstat(2), stat(2), symlink(2), realpath(3), path_resolution(7), symlink(7)

COLOPHON
Cette page fait partie de la publication 5.13 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>, Frédéric Hantrais <fhantrais@gmail.com> et Jean-Philippe MENGUAL <jpmengual@debian.org> Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 (https://www.gnu.org/licenses/gpl-3.0.html) 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.