web-dev-qa-db-fra.com

Qu'est-ce que `S_ISREG ()`, et que fait-il?

Je suis tombé sur la macro S_ISREG() dans un programme C qui récupère les attributs de fichier. Malheureusement, il n'y a aucune information de base sur cette macro en ligne. Il y a des discussions plus avancées à ce sujet, mais elles vont au-delà de ce que je recherche.

Qu'est-ce que S_ISREG(), et que fait-il? Dans le contexte d'un programme qui récupère des attributs de fichier, à quoi sert-il et exactement à quoi sert-il?

Merci.

14
The Pointer

S_ISREG () est une macro utilisée pour interpréter les valeurs dans un stat-struct, telles que renvoyées par l'appel système stat (). Il évalue à vrai si l'argument (le membre st_mode dans struct stat) est un fichier normal.

Voir man stat ou man fstat pour plus de détails. Voici la partie pertinente de la page de manuel:

   Because tests of the above form are common, additional macros are defined by POSIX to allow the test of the file type in st_mode to be written more concisely:

       S_ISREG(m)  is it a regular file?

       S_ISDIR(m)  directory?

       S_ISCHR(m)  character device?

       S_ISBLK(m)  block device?

       S_ISFIFO(m) FIFO (named pipe)?

       S_ISLNK(m)  symbolic link?  (Not in POSIX.1-1996.)

       S_ISSOCK(m) socket?  (Not in POSIX.1-1996.)

   The preceding code snippet could thus be rewritten as:

       stat(pathname, &sb);
       if (S_ISREG(sb.st_mode)) {
           /* Handle regular file */
       }
22
Bjorn A.

Le standard POSIX qui définit S_ISREG est en fait en ligne.

http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_stat.h.html

Citation:

Les macros suivantes doivent être fournies pour tester si un fichier est du type spécifié. La valeur m fournie aux macros est la valeur de st_mode à partir d'une stat structure. La macro doit être évaluée à une valeur non nulle si le test est vrai; 0 si le test est faux.

[...]

S_ISFIFO ( m)

Testez un tube ou FIFO fichier spécial.

S_ISREG ( m)

Testez un fichier normal.

S_ISLNK ( m)

Testez un lien symbolique.

[...]

Une façon typique d'utiliser S_ISREG consiste à appeler d'abord la fonction stat pour remplir un struct stat objet contenant des informations sur un fichier. Ensuite, la valeur de st_mode un membre de cette structure, de type entier, peut être testé avec cette macro.

En plus de la norme, il existe des pages de manuel de différents systèmes en ligne, ainsi que des tutoriels sur la programmation avec stat. Le Wikipedia a un page sur stat , avec un exemple de code apparemment complet. Bien qu'il ne comporte pas S_ISREG, qui peut facilement être travaillé.

4
Kaz

Il teste le membre st_mode De la structure stat récupéré à l'aide de la fonction stat() pour déterminer si le fichier est un fichier régulier (c'est-à-dire sur disque ou stockage de masse plutôt que de dire un répertoire, socket, lien symbolique par exemple.

struct stat sb;
if( stat( file_path, &sb) != -1) // Check the return value of stat
{
    if( S_ISREG( sb.st_mode ) != 0 )
    {
        printf( "%s is a file", file_path ) ;
    }
    else
    {
        printf( "%s is not a file", file_path ) ;
    }
}

Le membre st_mode Contient 4 bits masqués par S_IFMT (0170000). Les valeurs de ces bits sont:

       S_IFSOCK   0140000   socket
       S_IFLNK    0120000   symbolic link
       S_IFREG    0100000   regular file
       S_IFBLK    0060000   block device
       S_IFDIR    0040000   directory
       S_IFCHR    0020000   character device
       S_IFIFO    0010000   FIFO

de sorte que la macro S_ISREG peut être définie ainsi:

#define S_ISREG( m ) (((m) & S_IFMT) == S_IFREG)

Comme il s'agit d'une macro, vous pouvez consulter sa définition réelle dans le fichier d'en-tête sys/stat.h. Dans l'en-tête GNU il est défini comme ceci:

#define __S_ISTYPE(mode, mask)  (((mode) & __S_IFMT) == (mask))
...
#define S_ISREG(mode)    __S_ISTYPE((mode), __S_IFREG)

qui est essentiellement le même dans ma version simplifiée.

4
Clifford