READLINK(2) Manuel du programmeur Linux READLINK(2)

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

#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>
ssize_t readlinkat(int dirfd, const char *pathname,
                   char *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 versions <= 2.19: */ _BSD_SOURCE

readlinkat():

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

readlink() places the contents of the symbolic link pathname in the buffer buf, which has size bufsiz. readlink() does not append a null byte to buf. It will (silently) truncate the contents (to a length of bufsiz characters), in case the buffer is too small to hold all of the contents.

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

Since Linux 2.6.39, pathname can be an empty string, in which case the call operates on the symbolic link referred to by dirfd (which should have been obtained using open(2) with the O_PATH and O_NOFOLLOW flags).

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

On success, these calls return the number of bytes placed in buf. (If the returned value equals bufsiz, then truncation may have occurred.) On error, -1 is returned and errno is set to indicate the error.

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
The named file (i.e., the final filename component of pathname) is not a symbolic link.
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
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.

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 dirfd est un descripteur de fichier faisant référence à un fichier qui n'est pas un dossier.

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

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.

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.

Using a statically sized buffer might not provide enough room for the symbolic link contents. The required size for the buffer can be obtained from the stat.st_size value returned by a call to lstat(2) on the link. However, the number of bytes written by readlink() and readlinkat() should be checked to make sure that the size of the symbolic link did not increase between the calls. Dynamically allocating the buffer for readlink() and readlinkat() also addresses a common portability problem when using PATH_MAX for the buffer size, as this constant is not guaranteed to be defined per POSIX if the system does not have such limit.

On older kernels where readlinkat() is unavailable, the glibc wrapper function falls back to the use of readlink(). When pathname is a relative pathname, glibc constructs a pathname based on the symbolic link in /proc/self/fd that corresponds to the dirfd argument.

The following program allocates the buffer needed by readlink() dynamically from the information provided by lstat(2), falling back to a buffer of size PATH_MAX in cases where lstat(2) reports a size of zero.
#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);
    }
    /* Add one to the link size, so that we can determine whether
       the buffer returned by readlink() was truncated. */
    bufsiz = sb.st_size + 1;
    /* Some magic symlinks under (for example) /proc and /sys
       report 'st_size' as zero. In that case, take PATH_MAX as
       a "good enough" estimate. */
    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);
    }
    printf("'%s' points to '%.*s'\n", argv[1], (int) nbytes, buf);
    /* If the return value was equal to the buffer size, then the
       the link target was larger than expected (perhaps because the
       target was changed between the call to lstat() and the call to
       readlink()). Warn the user that the returned target may have
       been truncated. */
    if (nbytes == bufsiz)
        printf("(Returned buffer may have been truncated)\n");
    free(buf);
    exit(EXIT_SUCCESS);
}

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

Cette page fait partie de la publication 5.10 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/.

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 Frédéric Hantrais <fhantrais@gmail.com>

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.

9 juin 2020 Linux