Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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 are some more advanced discussions on it, but they go beyond what I'm looking for.

What is S_ISREG(), and what does it do? In the context of a program that retrieves file attributes, what purpose does it serve, and exactly what does it do?

Thank you.

like image 822
The Pointer Avatar asked Oct 20 '16 19:10

The Pointer


3 Answers

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 */
       }
like image 161
Bjorn A. Avatar answered Nov 03 '22 19:11

Bjorn A.


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.

like image 35
Clifford Avatar answered Nov 03 '22 18:11

Clifford


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.

like image 28
Kaz Avatar answered Nov 03 '22 17:11

Kaz