什么是`S_ISREG()`,它有什么作用?

Posted

技术标签:

【中文标题】什么是`S_ISREG()`,它有什么作用?【英文标题】:What is `S_ISREG()`, and what does it do? 【发布时间】:2017-03-02 23:24:45 【问题描述】:

我在一个检索文件属性的 C 程序中遇到了宏 S_ISREG()。不幸的是,网上没有关于这个宏的任何基本信息。对此有一些更高级的讨论,但它们超出了我的要求。

什么是S_ISREG(),它有什么作用?在检索文件属性的程序的上下文中,它的用途是什么?具体是做什么的?

谢谢。

【问题讨论】:

@Clifford 谢谢。关于这个宏的唯一其他问题是关于更高级的应用程序。 @ryyker 不,不是。如果您阅读您发布的问题,您会发现它侧重于更高级的应用程序。 @ryyker 这个问题假设你已经知道S_ISREG 的用途。 您可能必须链接到“高级应用程序”我仍在努力了解有关此问题的任何讨论如何变得复杂 - 除非您只是表示讨论处理的是使用S_ISREG 只是一小部分。 stat() 手册页中的示例显示了对 st_mode 的测试 - 这些宏只是将该测试包装成布尔结果。 您无需在线即可获取文档; man 2 stat 在 linux 上完美运行。 【参考方案1】:

S_ISREG() 是一个宏,用于解释从系统调用 stat() 返回的 stat-struct 中的值。如果参数(struct stat 中的 st_mode 成员)是常规文件,则计算结果为 true。

请参阅man statman fstatman inode (link to inode 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 */
       

【讨论】:

【参考方案2】:

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

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)

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

【讨论】:

你的 if-test 是倒置的。如果 S_ISREG() 不为零,则所讨论的对象是常规文件。 sourceware.org/git/?p=glibc.git;a=blob;f=io/sys/… 和 sourceware.org/git/?p=glibc.git;a=blob;f=bits/… 对于好奇的人【参考方案3】:

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

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

引用:

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

[...]

S_ISFIFO(m)

   测试管道或 FIFO 特殊文件。

S_ISREG(m)

   测试常规文件。

S_ISLNK(m)

   测试符号链接。

[...]

使用 S_ISREG 的典型方法是首先调用 stat 函数以使用有关文件的信息填充 struct stat 对象。那么这个结构的st_mode成员的值,一个整数类型,就可以用这个宏来测试了。

除了标准之外,还有来自各种在线系统的手册页,以及关于使用 stat 进行编程的教程。***有一个page on stat,有一个明显完整的代码示例。虽然它没有S_ISREG,但可以很容易地使用它。

【讨论】:

以上是关于什么是`S_ISREG()`,它有什么作用?的主要内容,如果未能解决你的问题,请参考以下文章

什么是修饰符?它有什么作用?举例说明

CDATA 到底是啥,它有啥作用?

什么是 SSIS 包,它有什么作用?

QEMU是啥软件?它有啥作用.用来干啥?

什么是OSPF协议?它有什么作用?

(5) 啥是WBS?它的作用是啥?