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

时间:2016-10-20 19:48:17

标签: c linux macos unix operating-system

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.

3 个答案:

答案 0 :(得分:21)

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 or man fstat 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 */
       }

答案 1 :(得分:4)

定义S_ISREG的POSIX标准实际上是在线的。

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

引用:

  

应提供以下宏来测试文件是否为指定类型。提供给宏的值 m 是来自 stat 结构的 st_mode 的值。如果测试为真,宏应评估为非零值;如果测试结果为假,则为0。

     

[...]

     

S_ISFIFO(

     

测试管道或FIFO特殊文件。

     

S_ISREG(

     

测试常规文件。

     

S_ISLNK(

     

测试符号链接。

     

[...]

使用S_ISREG的典型方法是首先调用stat函数以使用有关文件的信息填充struct stat对象。然后可以使用此宏测试此结构的st_mode成员的值(整数类型)。

除了标准之外,还有各种在线系统的手册页,以及有关使用stat编程的教程。维基百科有一个page on stat,有一个明显完整的代码示例。虽然它没有S_ISREG功能,但可以轻松使用。

答案 2 :(得分:3)

它测试使用st_mode函数检索的stat结构的stat()成员,以确定该文件是否是一个regualar文件(即在磁盘或大容量存储上,而不是说目录,套接字,符号链接,例如。

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

st_mode成员包含由S_IFMT(0170000)屏蔽的4位。这些位的值是:

       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

因此可以定义宏S_ISREG:

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

由于它是一个宏,你可以在头文件sys/stat.h中查看它的实际定义。在GNU标题中,它定义为:

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

在我的简化版本中基本相同。