What is `S_ISREG()`, and what does it do?

前端 未结 3 1715
时光说笑
时光说笑 2021-02-05 08:30

I came across the macro S_ISREG() in a C program that retrieves file attributes. Unfortunately, there isn\'t any basic information about this macro online. There ar

相关标签:
3条回答
  • 2021-02-05 08:55

    It tests the st_mode member of the stat structure retrieved using the stat() function to determine whether the file is a regualar file (i.e. on on disk or mass storage rather than say a directory, socket, symbolic link for example.

    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 ) ;
        }
    }
    

    The st_mode member contains 4 bits masked by S_IFMT (0170000). The values of these bits are:

           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
    

    so the macro S_ISREG mighte be defined thus:

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

    Since it is a macro you can look at its actual definition in the header file sys/stat.h. In the GNU header it is defined this:

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

    which is essentially the same at my simplified version.

    0 讨论(0)
  • 2021-02-05 09:01

    S_ISREG() is a macro used to interpret the values in a stat-struct, as returned from the system call stat(). It evaluates to true if the argument(The st_mode member in struct stat) is a regular file.

    See man stat, man fstat or man inode (link to inode man page) for further details. Here's the relevant part of the man page:

       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 */
           }
    
    0 讨论(0)
  • 2021-02-05 09:07

    The POSIX standard which defines S_ISREG is in fact online.

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

    Quote:

    The following macros shall be provided to test whether a file is of the specified type. The value m supplied to the macros is the value of st_mode from a stat structure. The macro shall evaluate to a non-zero value if the test is true; 0 if the test is false.

    [...]

    S_ISFIFO(m)

       Test for a pipe or FIFO special file.

    S_ISREG(m)

       Test for a regular file.

    S_ISLNK(m)

       Test for a symbolic link.

    [...]

    A typical way to use S_ISREG is to first call the stat function to fill a struct stat object with information about a file. Then the value of the st_mode member of this structure, an integer type, can be tested with this macro.

    In addition the standard, there are man pages from various systems online, as well as tutorials about programming with stat. The Wikipedia has a page on stat, with an apparently complete code example. Though it doesn't feature S_ISREG, that can easily be worked in.

    0 讨论(0)
提交回复
热议问题