STAT(2)

NOM
stat, fstat, lstat, fstatat - Obtenir l'état d'un fichier (file status)

SYNOPSIS
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int stat(const char *pathname, struct stat *buf);
int fstat(int fd, struct stat *buf);
int lstat(const char *pathname, struct stat *buf);

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

int fstatat(int dirfd, const char *pathname, struct stat *buf,
            int flags);

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

lstat() :
    /* glibc 2.19 et versions précédentes */ _BSD_SOURCE ||
    /* Depuis la glibc 2.20 */_DEFAULT_SOURCE ||
    _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
    || /* Depuis la glibc 2.10 : */ _POSIX_C_SOURCE >= 200112L

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

DESCRIPTION

Ces fonctions renvoient des renseignements sur le fichier indiqué, dans le tampon pointé par stat. Vous n'avez besoin d'aucun droit d'accès au fichier pour obtenir les informations, mais vous devez — dans le cas de stat(), fstatat() et lstat() — avoir le droit de parcours de tous les répertoires mentionnés dans le chemin menant au fichier.

stat() et fstatat() récupèrent des renseignements sur le fichier pointé par pathname. Les différences de fstatat() sont décrites ci-dessous : lstat() est identique à stat(), sauf que dans le cas où pathname est un lien symbolique, auquel cas il renvoie des renseignements sur le lien lui-même plutôt que celui du fichier visé. fstat() est identique à stat(), sauf que le fichier dont les renseignements sont à récupérer est référencé par le descripteur de fichier fd.

Les trois fonctions renvoient une structure stat contenant les champs suivants :

struct stat {
    dev_t     st_dev;         /* Périphérique                     */
    ino_t     st_ino;         /* Numéro d’inœud                   */
    mode_t    st_mode;        /* Protection                       */
    nlink_t   st_nlink;       /* Nombre de liens physiques        */
    uid_t     st_uid;         /* UID du propriétaire              */
    gid_t     st_gid;         /* GID du propriétaire              */
    dev_t     st_rdev;        /* Type de périphérique             */
    off_t     st_size;        /* Taille totale en octets          */
    blksize_t st_blksize;     /* Taille de bloc pour E/S          */
    blkcnt_t  st_blocks;      /* Nombre de blocs de 512 o alloués */
    /* Depuis Linux 2.6, le noyau permet une précision à la
       nanoseconde pour les champs temporels suivants. Pour
       plus de précisions avant Linux 2.6, consultez les NOTES.   */
    struct timespec st_atim;  /* Heure dernier accès              */
    struct timespec st_mtim;  /* Heure dernière modification      */
    struct timespec st_ctim;  /* Heure dernier changement état    */
#define st_atime st_atim.tv_sec      /* Rétrocompatibilité        */
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec
};
Remarque : l’ordre des champs de la structure stat varie un peu en fonction des architectures. De plus, la définition ci-dessus ne montre pas les octets de remplissage qui pourraient être présents entre certains champs sur plusieurs architectures. Consultez les sources de la glibc et du noyau pour plus de précisions. Le champ st_dev décrit le périphérique sur lequel ce fichier réside. Les macros major(3) et minor(3) peuvent être utiles pour décomposer l'identifiant de périphérique de ce champ. Le champ st_rdev indique le périphérique que ce fichier (inœud) représente. Le champ st_size indique la taille du fichier (s'il s'agit d'un fichier ordinaire ou d'un lien symbolique) en octets. La taille d'un lien symbolique est la longueur de la chaîne représentant le chemin d'accès qu'il vise, sans le caractère NUL final. Le champ st_blocks indique le nombre de blocs de 512 octets alloués au fichier. Cette valeur peut être inférieure à st_size/512 si le fichier a des trous. Le champ st_blksize donne la taille de bloc « préférée » pour des entrées-sorties efficaces. Des écritures par blocs plus petits peuvent entraîner un cycle lecture/modification/réécriture inefficace.

Tous les systèmes de fichiers de Linux n'implémentent pas tous les champs liés à la date. Certains systèmes de fichiers autorisent le montage de telle manière que les accès à des fichiers et/ou répertoires ne modifient pas le champ st_atime (voir les options noatime, nodiratime et relatime de mount(8) ainsi que les informations correspondante dans mount(2)). De plus, st_atime n'est pas mis à jour si un fichier est ouvert avec l'option O_NOATIME ; consultez open(2). Le champ st_atime est modifié par les accès au fichier, par exemple avec execve(2), mknod(2), pipe(2), utime(2) et read(2) (d'au moins un octet). D'autres routines, comme mmap(2), peuvent ou non mettre à jour ce champ st_atime. Le champ st_mtime est modifié par des changements sur le fichier lui-même, c'est-à-dire mknod(2), truncate(2), utime(2) et write(2) (d'au moins un octet). D'autre part, le champ st_mtime d'un répertoire est modifié lors de la création ou la suppression de fichiers en son sein. Le champ st_mtime n'est pas mis à jour lors de modification de propriétaire, groupe, mode ou nombre de liens physiques. Le champ st_ctime est modifié lors d'une écriture ou une modification de données concernant l'inœud (propriétaire, groupe, mode, etc.).

Les valeurs de masque suivantes sont définies pour le composant de type de fichier du champ st_mode :
S_IFMT | 0170000 | masque du type de fichier
S_IFSOCK | 0140000 | socket
S_IFLNK | 0120000 | lien symbolique
S_IFREG | 0100000 | fichier ordinaire
S_IFBLK | 0060000 | périphérique bloc
S_IFDIR | 0040000 | répertoire
S_IFCHR | 0020000 | périphérique caractère
S_IFIFO | 0010000 | fifo

Ainsi, pour tester (par exemple) un fichier régulier, il est possible d’écrire :
stat(pathname, &sb);
if ((sb.st_mode & S_IFMT) == S_IFREG) {
    /* Traiter les fichiers normaux */
}

Puisque les tests de la forme précédente sont usuels, des macros supplémentaires sont définies par POSIX pour permettre d’écrire le test de type de fichier dans st_mode de façon plus concise :

    S_ISREG(m)
        est-ce un fichier ordinaire ?

    S_ISDIR(m)
        un répertoire ?

    S_ISCHR(m)
        un périphérique caractère ?

    S_ISBLK(m)
        un périphérique bloc ?

    S_ISFIFO(m)
        un FIFO (tube nommé) ?

    S_ISLNK(m)
        un lien symbolique ? (Pas dans POSIX.1-1996).

    S_ISSOCK(m)
        une socket ? (Pas dans POSIX.1-1996).

Le morceau de code précédent pourrait donc être réécrit comme ceci :
stat(pathname, &sb);
if (S_ISREG(sb.st_mode)) {
    /* Traiter les fichiers normaux */
}

Les définitions de la plupart des macros de test de type de fichier précédentes sont fournies si une des macros de test de fonctionnalité suivantes est définie : _BSD_SOURCE (dans glibc 2.19 et versions précédentes), _SVID_SOURCE (dans glibc 2.19 et versions précédentes) ou _DEFAULT_SOURCE (dans glibc 2.20 et versions suivantes). De plus les définitions de toutes les macros précédentes à part S_IFSOCK et S_ISSOCK() sont fournies si _XOPEN_SOURCE est définie. La définition de S_IFSOCK peut aussi être exposée en définissant _XOPEN_SOURCE avec une valeur de 500 ou plus. La définition de S_ISSOCK() est exposée si une des macros de test de fonctionnalité suivante est définie : _BSD_SOURCE (dans glibc 2.19 et versions précédentes), _DEFAULT_SOURCE (dans glibc 2.20 et versions suivantes), _XOPEN_SOURCE avec une valeur de 500 ou plus ou _POSIX_C_SOURCE avec une valeur de 200112L ou plus.

Les valeurs de masque suivantes sont définies pour le composant de droits de fichier du champ st_mode :
S_ISUID | 0004000 | bit Set-UID
S_ISGID | 0002000 | bit Set-Gid (voir ci-dessous)
S_ISVTX | 0001000 | bit « sticky » (voir ci-dessous)
S_IRWXU | 00700 | masque de droits du propriétaire pour le fichier
S_IRUSR | 00400 | le propriétaire a le droit de lecture
S_IWUSR | 00200 | le propriétaire a le droit d'écriture
S_IXUSR | 00100 | le propriétaire a le droit d'exécution
S_IRWXG | 00070 | masques de droits du groupe
S_IRGRP | 00040 | le groupe a le droit de lecture
S_IWGRP | 00020 | le groupe a le droit d'écriture
S_IXGRP | 00010 | le groupe a le droit d'exécution
S_IRWXO | 00007 | masque de droits des autres (pas dans le groupe)
S_IROTH | 00004 | les autres ont le droit de lecture
S_IWOTH | 00002 | les autres ont le droit d'écriture
S_IXOTH | 00001 | les autres ont le droit d'exécution

Le bit Set-GID (S_ISGID) a plusieurs utilisations particulières : pour un répertoire, il indique que la sémantique BSD doit être appliquée en son sein, c'est-à-dire que les fichiers qui y sont créés héritent leur GID du répertoire et non pas du GID effectif du processus créateur, et les sous-répertoires auront automatiquement le bit S_ISGID actif. Pour les fichiers qui n'ont pas d'autorisation d'exécution pour le groupe (S_IXGRP non actif), ce bit indique qu'un verrouillage strict est en vigueur sur ce fichier.

Le bit « sticky » (S_ISVTX) sur un répertoire indique que les fichiers qui s'y trouvent ne peuvent être renommés ou effacés que par leur propriétaire, par le propriétaire du répertoire ou par un processus privilégié.

  fstatat()
L'appel système fstatat() fonctionne exactement comme stat(2), les seules différences étant celles 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, comme dans stat(). Si pathname est relatif, et si dirfd est la valeur spéciale AT_FDCWD, pathname est interprété comme étant relatif au répertoire courant du processus appelant, comme stat(). Si pathname est un chemin absolu, dirfd est ignoré. L'argument flags est soit 0, soit un OU binaire « | » avec les options suivantes :

AT_EMPTY_PATH (depuis Linux 2.6.39)
    Si pathname est une chaîne vide, opérer sur le fichier référencé par dirfd (qui peut avoir été obtenu en utilisant open(2) avec l’attribut O_PATH). Si dirfd est AT_FDCWD, l’appel opère sur le répertoire de travail actuel. Dans ce cas, dirfd peut référencer tout type de fichier, pas uniquement un répertoire. Cet attribut est spécifique à Linux, _GNU_SOURCE doit être définie pour obtenir sa définition.

AT_NO_AUTOMOUNT (depuis Linux 2.6.38)
    N'attache pas automatiquement le composant terminal (nom de base) de pathname s'il s'agit d'un répertoire qui est un point de montage automatique. Cela permet à l'appelant de rassembler les attributs d'un point de montage automatique (plutôt que l'emplacement qu'il attacherait). Ce drapeau peut être utilisé dans des outils qui analysent les répertoires pour éviter un montage automatique en masse d'un répertoire contenant des points de montage automatique. Le drapeau AT_NO_AUTOMOUNT n'a aucun effet si le point de montage est déjà attaché. Ce drapeau est spécifique à Linux, _GNU_SOURCE doit être définie pour obtenir sa définition.

AT_SYMLINK_NOFOLLOW
    Si pathname est un lien symbolique, ne pas le déréférencer, mais renvoyer des informations sur le lien lui-même, comme le fait lstat(2). (Par défaut, fstatat() suit les liens symboliques, comme stat(2).)

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

VALEUR RENVOYÉE
S'il réussit, cet appel système renvoie 0. S'il échoue, il renvoie -1 et remplit errno en conséquence.

ERREURS

EACCES
    La permission de parcours est refusée pour un des répertoires contenu dans le chemin pathname. (Consultez aussi path_resolution(7).)

EBADF
    fd est un mauvais descripteur.

EFAULT
    Un pointeur se trouve en dehors de l'espace d'adressage.

ELOOP
    Trop de liens symboliques rencontrés dans le chemin d'accès.

ENAMETOOLONG
    pathname est trop long.

ENOENT
    Un composant du chemin pathname n'existe pas, ou pathname est une chaîne vide.

ENOMEM
    Pas assez de mémoire (mémoire noyau).

ENOTDIR
    Un élément du préfixe du chemin pathname n'est pas un répertoire.

EOVERFLOW
    pathname ou fd se réfèrent à un fichier dont la taille, l'inœud ou le nombre de blocs ne peut pas être représenté respectivement avec le type off_t, ino_t ou blkcnt_t. Cela peut arriver par exemple quand une application compilée sans l'option -D_FILE_OFFSET_BITS=64 sur une plate-forme 32 bits appelle stat() pour un fichier dont la taille est supérieure à (1<<31)-1 octets.

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

EBADF
    dirfd n'est pas un descripteur de fichier valable.

EINVAL
    flags contient un attribut invalide.

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

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

CONFORMITÉ
stat(), fstat(), lstat() : SVr4, 4.3BSD, POSIX.1-2001, POSIX.1.2008. fstatat() : POSIX.1-2008. D'après POSIX.1-2001, lstat() sur un lien symbolique ne doit renvoyer des informations valables que dans le champ st_size et pour le composant de type de fichier du champ st_mode de la structure stat. POSIX.1-2008 renforce la spécification, obligeant lstat() à renvoyer des informations valables dans tous les champs à part les bits de droit de st_mode. L'utilisation des champs st_blocks et st_blksize risque d'être moins portable (ils ont été introduits dans BSD. Leur interprétation change suivant les systèmes, voire sur un même système s'il y a des montages NFS). Si vous avez besoin de connaître la définition des types blkcnt_t ou blksize_t de <sys/stat.h>, alors définissez _XOPEN_SOURCE avec une valeur supérieure ou égale à 500 (avant d'inclure tout en-tête).

POSIX.1-1990 ne décrivait pas les constantes S_IFMT, S_IFSOCK, S_IFLNK, S_IFREG, S_IFBLK, S_IFDIR, S_IFCHR, S_IFIFO, S_ISVTX, mais réclamait d'utiliser les macros S_ISDIR(), etc. Les constantes S_IF*() sont présentes dans POSIX.1-2011 et versions suivantes. Les macros S_ISLNK() et S_ISSOCK() ne se trouvent pas dans POSIX.1-1996 mais sont présentes dans POSIX.1-2001. La première vient de SVID 4, la seconde de SUSv2.

UNIX V7 (et les systèmes suivants) propose S_IREAD, S_IWRITE, S_IEXEC, là où POSIX préfère leurs synonymes S_IRUSR, S_IWUSR, S_IXUSR.

  Autres systèmes
Voici quelques valeurs qui ont été (ou sont) utilisées sur d'autres systèmes
hex | nom | ls | octal | description
f000 | S_IFMT |  | 170000 | masque du type de fichier
0000 |  |  | 000000 | inœud hors-service (SCO) ; type inconnu (BSD) ; SVID-v2 et XPG2 ont 0 et 0100000 pour « fichier ordinaire »
1000 | S_IFIFO | p| | 010000 | fifo (tube nommé)
2000 | S_IFCHR | c | 020000 | fichier spécial caractère (V7)
3000 | S_IFMPC |  | 030000 | fichier spécial caractère multiplexé
 |  |  |  | (V7)
4000 | S_IFDIR | d/ | 040000 | répertoire (V7)
5000 | S_IFNAM |  | 050000 | fichier spécial nommé XENIX avec deux sous-types distingués par st_rdev valant 1 ou 2
0001 | S_INSEM | s | 000001 | sous-type sémaphore de IFNAM XENIX
0002 | S_INSHD | m | 000002 | sous-type données partagées de IFNAM
 |  |  |  | XENIX
6000 | S_IFBLK | b | 060000 | fichier spécial bloc (V7)
7000 | S_IFMPB |  | 070000 | fichier spécial bloc multiplexé (V7)
8000 | S_IFREG | - | 100000 | fichier normal (V7)
9000 | S_IFCMP |  | 110000 | compressé VxFS
9000 | S_IFNWK | n | 110000 | fichier spécial réseau (HP-UX)
a000 | S_IFLNK | l@ | 120000 | lien symbolique (BSD)
b000 | S_IFSHAD |  | 130000 | inœud shadow Solaris pour l'ACL (invisible depuis l'espace utilisateur)
c000 | S_IFSOCK | s= | 140000 | socket (BSD ; aussi "S_IFSOC" sur VxFS)
d000 | S_IFDOOR | D> | 150000 | Solaris door
e000 | S_IFWHT | w% | 160000 | correcteur BSD (inutilisé pour les
 |  |  |  | inœuds)
0200 | S_ISVTX |  | 001000 | « sticky bit » : garder en mémoire après exécution (V7) réservé (SVID-v2) non répertoires : ne pas placer ce fichier en cache (SunOS) répertoires : attribut de restrictions d'effacement (SVID-v4.2)
0400 | S_ISGID |  | 002000 | définir le GID à l'exécution (V7) pour les répertoires : sémantique BSD pour la propagation du GID
0400 | S_ENFMT |  | 002000 | verrouillage strict System V (partagé avec S_ISGID)
0800 | S_ISUID |  | 004000 | définir l'UID à l'exécution (V7)
0800 | S_CDF |  | 004000 | le répertoire est un fichier dépendant du contexte (HP-UX)
Une commande sticky est apparue dans la version 32V d'AT&T UNIX.

NOTES
Sous Linux, lstat() ne provoque généralement pas d'action de l'« automonteur », tandis que stat() le fera (mais consultez fstatat(2)). Pour la plupart des fichiers sous /proc, stat() ne renvoie pas la taille du fichier dans le champ st_size. La valeur 0 est placée dans ce champ.

  Champs temporels
Les anciens noyaux et les anciennes normes ne permettaient pas d’utiliser des champs temporels en nanoseconde. À la place, trois champs temporels — st_atime, st_mtime et st_ctime — étaient utilisés pour time_t qui enregistraient des horodatages avec une précision à la seconde. Depuis le noyau 2.5.48, la structure stat permet une résolution d'une nanoseconde pour les trois champs temporels. Les composants en nanoseconde de chaque horodatage sont disponibles en utilisant des noms de la forme st_atim.tv_nsec si une des macros de test de fonctionnalités _BSD_SOURCE ou _SVID_SOURCE est définie. Les horodatages en nanoseconde sont maintenant définis, depuis POSIX.1-2008 et, à partir de la version 2.12, la glibc expose aussi ces noms de composant en nanoseconde si _POSIX_C_SOURCE est définie avec une valeur supérieure ou égale à 200809L ou si _XOPEN_SOURCE est définie avec une valeur supérieure ou égale à 700. Si aucune de ces macros ne sont définies, alors les valeurs en nanosecondes sont exposées avec des noms de la forme st_atimensec. Les horodatages en nanoseconde sont permis sur les systèmes de fichiers XFS, JFS, Btrfs et ext4 (depuis Linux 2.6.23). Les horodatages en nanoseconde ne sont pas permis sur les systèmes de fichiers ext2, ext3 et Reiserfs. Sur les systèmes de fichiers qui ne permettent pas les résolutions inférieures à la seconde, ces champs en nanoseconde prennent la valeur 0.

  Interface noyau sous-jacente
Avec le temps, l'augmentation de la taille de la structure stat a conduit à 3 versions successives de stat() : sys_stat() (entrée __NR_oldstat), sys_newstat() (entrée __NR_stat) et sys_stat64() (nouveauté du noyau 2.4 ; entrée __NR_stat64). La fonction stat() fournie par la glibc cache ces détails aux applications, en appelant la version la plus récente de l'appel système fournie par le noyau et en réorganisant si nécessaire les informations renvoyées pour les anciens binaires. La même remarque s'applique à fstat() et lstat(). L'appel système sous-jacent à la fonction fstatat() de la glibc s'appelle fstatat64().

EXEMPLE
Le programme suivant appelle stat() et affiche certains champs sélectionnés dans la structure stat renvoyée.
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
    struct stat sb;
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <pathname>\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    if (stat(argv[1], &sb) == -1) {
        perror("stat");
        exit(EXIT_FAILURE);
    }
    printf("Type de fichier :                  ");
    switch (sb.st_mode & S_IFMT) {
    case S_IFBLK:  printf("périphérique bloc\n");       break;
    case S_IFCHR:  printf("périphérique caractère\n");  break;
    case S_IFDIR:  printf("répertoire\n");              break;
    case S_IFIFO:  printf("FIFO/tube\n");               break;
    case S_IFLNK:  printf("lien symbolique\n");         break;
    case S_IFREG:  printf("fichier ordinaire\n");       break;
    case S_IFSOCK: printf("socket\n");                  break;
    default:       printf("inconnu ?\n");               break;
    }
    printf("Numéro d'inœud :                   %ld\n", (long) sb.st_ino);
    printf("Mode :                             %lo (octal)\n",
            (unsigned long) sb.st_mode);
    printf("Nombre de liens :                  %ld\n",
            (long) sb.st_nlink);
    printf("Propriétaires :                    UID=%ld   GID=%ld\n",
            (long) sb.st_uid, (long) sb.st_gid);
    printf("Taille de bloc d'E/S :             %ld octets\n",
            (long) sb.st_blksize);
    printf("Taille du fichier :                %lld octets\n",
            (long long) sb.st_size);
    printf("Blocs alloués :                    %lld\n",
            (long long) sb.st_blocks);
    printf("Dernier changement d'état :        %s", ctime(&sb.st_ctime));
    printf("Dernier accès au fichier :         %s", ctime(&sb.st_atime));
    printf("Dernière modification du fichier : %s", ctime(&sb.st_mtime));
    exit(EXIT_SUCCESS);
}

VOIR AUSSI
ls(1), stat(1), access(2), chmod(2), chown(2), readlink(2), utime(2), capabilities(7), symlink(7)

COLOPHON
Cette page fait partie de la publication 3.70 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 à <perkamon-fr@traduc.org>.

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