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.
答案 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)
在我的简化版本中基本相同。