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.
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 */
}
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With