STAT

Section : Manuel du programmeur Linux (2)
Mise à jour de la version anglaise : 26 juillet 2007
Index Menu principal  

NOM

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

SYNOPSIS

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

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

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

lstat() : _BSD_SOURCE || _XOPEN_SOURCE >= 500  

DESCRIPTION

Ces fonctions renvoient des informations à propos d'un fichier. Aucune permission n'est nécessaire sur le fichier lui-même, mais vous devez --- dans le cas de stat() et lstat() --- avoir la permission d'exécution (parcours) pour tous les répertoires de path qui mènent au fichier.

stat() récupère l'état du fichier pointé par path et remplit le tampon buf.

lstat() est identique à stat(), sauf que si path est un lien symbolique, il donne l'état du lien lui-même plutôt que celui du fichier visé.

fstat() est identique à stat(), sauf que le fichier ouvert est pointé par le descripteur fd, obtenu avec open(2).

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

struct stat {
    dev_t     st_dev;      /* ID du périphérique contenant le fichier */
    ino_t     st_ino;      /* Numéro inœud */
    mode_t    st_mode;     /* Protection */
    nlink_t   st_nlink;    /* Nb liens matériels */
    uid_t     st_uid;      /* UID propriétaire */
    gid_t     st_gid;      /* GID propriétaire */
    dev_t     st_rdev;     /* ID périphérique (si fichier spécial) */
    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 alloués */
    time_t    st_atime;    /* Heure dernier accès */
    time_t    st_mtime;    /* Heure dernière modification */
    time_t    st_ctime;    /* Heure dernier changement état */
};

Le champ st_dev indique le périphérique sur lequel réside le fichier. 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 régulier 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 l'octet 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 contient des trous). Le champ st_blksize indique la taille de bloc « préférée » pour les entrées-sorties du système de fichiers (l'écriture dans un fichier par petits morceaux peut induire de nombreuses étapes lecture-modification-écriture peu efficaces).

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 ne modifient pas le champ st_atime (voir l'option « noatime » de mount(8)).

Le champ st_atime est modifié par les accès au fichier, c'est-à-dire 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 macros POSIX suivantes sont fournies pour vérifier le type de fichier en utilisant le champ stmode :

S_ISREG(m)
un fichier ordinaire ?
S_ISDIR(m)
un répertoire ?
S_ISCHR(m)
un périphérique en mode caractère ?
S_ISBLK(m)
un périphérique en mode bloc ?
S_ISFIFO(m)
une FIFO (tube nommé) ?
S_ISLNK(m)
un lien symbolique ? (Pas dans POSIX.1-1996).
S_ISSOCK(m)
une socket ? (Pas dans POSIX.1-1996).

Les attributs suivants correspondent au champ st_mode :
S_IFMT0170000masque du type de fichier
S_IFSOCK0140000socket
S_IFLNK0120000lien symbolique
S_IFREG0100000fichier ordinaire
S_IFBLK0060000périphérique blocs
S_IFDIR0040000répertoire
S_IFCHR0020000périphérique caractères
S_IFIFO0010000fifo
S_ISUID0004000bit set-UID
S_ISGID0002000bit set-GID (voir plus loin)
S_ISVTX0001000bit « sticky » (voir plus loin)
S_IRWXU00700lecture/écriture/exécution du propriétaire
S_IRUSR00400le propriétaire a le droit de lecture
S_IWUSR00200le propriétaire a le droit d'écriture
S_IXUSR00100le propriétaire a le droit d'exécution
S_IRWXG00070lecture/écriture/exécution du groupe
S_IRGRP00040le groupe a le droit de lecture
S_IWGRP00020le groupe a le droit d'écriture
S_IXGRP00010le groupe a le droit d'exécution
S_IRWXO00007lecture/écriture/exécution des autres
S_IROTH00004les autres ont le droit de lecture
S_IWOTH00002les autres ont le droit d'écriture
S_IXOTH00001les 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é.  

VALEUR RENVOYÉE

Ces appels système retournent zéro s'ils réussissent. En cas d'échec, -1 est renvoyé, et errno contient le code de l'erreur.  

ERREURS

EACCES
La permission de parcours est refusée pour un des répertoires contenu dans le chemin path. (Voir 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
Nom de fichier trop long.
ENOENT
Un élément du chemin d'accès path n'existe pas, ou il s'agit d'une chaîne vide.
ENOMEM
Pas assez de mémoire pour le noyau.
ENOTDIR
Un élément du chemin d'accès n'est pas un répertoire.
 

CONFORMITÉ

Ces appels système sont conformes à SVr4, BSD 4.3, POSIX.1-2001.

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.

POSIX ne décrit pas les bits S_IFMT, S_IFSOCK, S_IFLNK, S_IFREG, S_IFBLK, S_IFDIR, S_IFCHR, S_IFIFO, S_ISVTX, mais réclame d'utiliser les macros S_ISDIR(), etc. 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
hexnomlsoctaldescription
f000S_IFMT170000Masque du type de fichier
0000000000inœud hors service (SCO) ; type BSD
inconnu ; SVID-v2 et XPG2 ont 0
et 0100000 pour un fichier ordinaire
1000S_IFIFOp|010000FIFO (tube nommé)
2000S_IFCHRc020000fichier spécial caractère (V7)
3000S_IFMPC030000fichier spécial caractère multiplexé (V7)
4000S_IFDIRd/040000répertoire (V7)
5000S_IFNAM050000fichier spécial nommé XENIX avec deux
sous-types distingués par
st_rdev valant 1 ou 2
0001S_INSEMs000001sous-type sémaphore de IFNAM XENIX
0002S_INSHDm000002sous-type données partagées de IFNAM XENIX
6000S_IFBLKb060000fichier spécial bloc (V7)
7000S_IFMPB070000fichier spécial bloc multiplexé (V7)
8000S_IFREG-100000fichier normal (V7)
9000S_IFCMP110000compressé VxFS
9000S_IFNWKn110000fichier spécial réseau (HP-UX)
a000S_IFLNKl@120000lien symbolique (BSD)
b000S_IFSHAD130000Fichier shadow Solaris pour l'ACL
(invisible depuis l'espace utilisateur)
c000S_IFSOCKs=140000socket (BSD; aussi "S_IFSOC" sur VxFS)
d000S_IFDOORD>150000Solaris door
e000S_IFWHTw%160000BSD whiteout (non utilisé pour les inœuds)

0200S_ISVTX001000« sticky bit » : garder en mémoire après
exécution (V7) réservé (SVID-v2)
non-répertoires : ne pas swapper
le fichier (SunOS)
répertoires : attributs de restrictions
d'effacement (SVID-v4.2)
0400S_ISGID002000Utiliser le GID à l'exécution (V7)
pour les répertoires : sémantique
BSD propageant le GID
0400S_ENFMT002000Verrouillage strict System V
(partagé avec S_ISGID)
0800S_ISUID004000Utiliser l'UID à l'exécution (V7)
0800S_CDF004000Le 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

 

Notes Linux

Depuis le noyau 2.5.48, la structure stat propose une résolution d'une nanoseconde pour les trois champs d'horodatage des fichiers. La glibc montre le composant nanoseconde de chaque champ en utilisant des noms soit de la forme st_atim.tv_nsec, si la macro de test de fonctionnalité _BSD_SOURCE ou _SVID_SOURCE est définie, soit de la forme st_atimensec, si aucune de ces macros n'est définie. Sur les systèmes de fichiers qui ne gèrent pas les résolutions inférieure à la seconde, ces champs nanosecondes sont renvoyés avec la valeur 0.

Pour la plupart des fichiers du répertoire /proc, stat() ne renvoie pas la taille du fichier dans le champ st_size ; à la place, le champ contient la valeur 0.  

Interface noyau sous-jacente

Au fil du temps, l'augmentation de la taille de la structure stat a conduit à trois 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 enveloppe stat() de la glibc cache ces détails aux applications, invoquant la version la plus récente de l'appel système fourni par le noyau, et réorganisant, si nécessaire, l'information renvoyée pour les anciens binaires. Les mêmes remarques s'appliquent à fstat() et lstat().  

EXEMPLE

Le programme suivant appelle stat() et affiche les 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_SUCCESS);
    }

    printf("Type de fichier :                ");

    switch (sb.st_mode & S_IFMT) {
    case S_IFBLK:  printf("périphérique de bloc\n");      break;
    case S_IFCHR:  printf("périphérique de 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

access(2), chmod(2), chown(2), fstatat(2), readlink(2), utime(2), capabilities(7), symlink(7)  

TRADUCTION

Ce document est une traduction réalisée par Christophe Blaess <http://www.blaess.fr/christophe/> le 15 octobre 1996 et révisée le 2 juillet 2008.

L'équipe de traduction a fait le maximum pour réaliser une adaptation française de qualité. La version anglaise la plus à jour de ce document est toujours consultable via la commande : « LANG=C man 2 stat ». N'hésitez pas à signaler à l'auteur ou au traducteur, selon le cas, toute erreur dans cette page de manuel.

 

Index

NOM
SYNOPSIS
DESCRIPTION
VALEUR RENVOYÉE
ERREURS
CONFORMITÉ
Autres systèmes
NOTES
Notes Linux
Interface noyau sous-jacente
EXEMPLE
VOIR AUSSI
TRADUCTION

Dernière mise à jour : 2 juillet 2008