跳转到内容

C 编程/POSIX 参考/sys/stat.h

来自维基教科书,开放书籍,开放世界

<sys/stat.h>C POSIX 库 中用于 C 编程语言 的头文件,其中包含用于获取文件属性信息的构造。

成员函数

[编辑 | 编辑源代码]
名称 注释
int stat (const char *filename, struct stat *buf) The stat 函数返回由 filename 指示的文件的属性信息,存储在 buf 指向的结构中。如果 filename 是一个符号链接的名称,那么您获得的属性将描述链接指向的文件。如果链接指向一个不存在的文件名,则 stat 会失败并报告不存在的文件。如果操作成功,则返回值为 0,否则为 -1。当源代码使用 _FILE_OFFSET_BITS == 64 编译时,此函数实际上是 stat64,因为 LFS 接口透明地替换了正常的实现。

errno 错误:ENOENT 表示由 filename 指示的文件不存在。

int stat64 (const char *filename, struct stat64 *buf) 此函数类似于 stat,但它也能在 32 位系统上处理大于 2^31 字节的文件。为了实现这一点,结果存储在一个类型为 struct stat64 的变量中,buf 必须指向该变量。当源代码使用 _FILE_OFFSET_BITS == 64 编译时,此函数在 32 位机器上以 stat 的名称可用,因此透明地替换了小型文件接口。

errno 错误:ENOENT 表示由 filename 指示的文件不存在。

int fstat (int filedes, struct stat *buf) fstat 函数类似于 stat,只是它接受一个打开的文件描述符 (filedes) 作为参数,而不是文件名。与 stat 一样,fstat 在成功时返回 0,在失败时返回 -1。当源代码使用 _FILE_OFFSET_BITS == 64 编译时,此函数实际上是 fstat64,因为 LFS 接口透明地替换了正常的实现。

errno 错误:EBADF 表示 filedes 参数不是有效的文件描述符。

int fstat64 (int filedes, struct stat64 *buf) 此函数类似于 fstat,但能够在 32 位平台上处理大型文件。对于大型文件,文件描述符 filedes 应该通过 open64 或 creat64 获取。buf 指针指向一个类型为 struct stat64 的变量,该变量能够表示更大的值。当源代码使用 _FILE_OFFSET_BITS == 64 编译时,此函数在 32 位机器上以 fstat 的名称可用,因此透明地替换了小型文件接口。

errno 错误:EBADF 表示 filedes 参数不是有效的文件描述符。

int lstat (const char *filename, struct stat *buf) lstat 函数类似于 stat,只是它不跟踪符号链接。如果 filename 是一个符号链接的名称,则 lstat 返回有关链接本身的信息;否则 lstat 类似于 stat。请参阅符号链接。当源代码使用 _FILE_OFFSET_BITS == 64 编译时,此函数实际上是 lstat64,因为 LFS 接口透明地替换了正常的实现。
int lstat64 (const char *filename, struct stat64 *buf) lstat 函数类似于 stat,只是它不跟踪符号链接。如果 filename 是一个符号链接的名称,则 lstat 返回有关链接本身的信息;否则 lstat 类似于 stat。请参阅符号链接。当源代码使用 _FILE_OFFSET_BITS == 64 编译时,此函数实际上是 lstat64,因为 LFS 接口透明地替换了正常的实现。

成员常量

[编辑 | 编辑源代码]

以下 POSIX 宏定义用于使用 st_mode 字段检查文件类型

名称 注释
S_ISREG(m) 它是一个普通文件吗?
S_ISDIR(m) 它是一个目录吗?
S_ISCHR(m) 它是一个字符设备吗?
S_ISBLK(m) 它是一个块设备吗?
S_ISFIFO(m) 它是一个 FIFO(命名管道)吗?
S_ISLNK(m) 它是一个符号链接吗?(在 POSIX.1-1996 中没有。)
S_ISSOCK(m) 它是一个套接字吗?(在 POSIX.1-1996 中没有。)

以下标志定义用于 st_mode 字段

名称 注释
S_IFMT 0170000 文件类型位字段的位掩码
S_IFSOCK 0140000 套接字
S_IFLNK 0120000 符号链接
S_IFREG 0100000 普通文件
S_IFBLK 0060000 块设备
S_IFDIR 0040000 目录
S_IFCHR 0020000 字符设备
S_IFIFO 0010000 FIFO
S_ISUID 0004000 设置 UID 位
S_ISGID 0002000 设置组 ID 位(见下文)
S_ISVTX 0001000 粘滞位(见下文)
S_IRWXU 00700 文件所有者权限的掩码
S_IRUSR 00400 所有者具有读取权限
S_IWUSR 00200 所有者具有写入权限
S_IXUSR 00100 所有者具有执行权限
S_IRWXG 00070 组权限的掩码
S_IRGRP 00040 组具有读取权限
S_IWGRP 00020 组具有写入权限
S_IXGRP 00010 组具有执行权限
S_IRWXO 00007 其他人(不在组中)的权限掩码
S_IROTH 00004 其他人具有读取权限
S_IWOTH 00002 其他人具有写入权限
S_IXOTH 00001 其他人具有执行权限

设置组 ID 位 (S_ISGID) 具有多种特殊用途。对于目录,它表示要对该目录使用 BSD 语义:在该目录中创建的文件将继承其组 ID,而不是创建进程的有效组 ID,并且在该目录中创建的目录也将设置 S_ISGID 位。对于没有设置组执行位 (S_IXGRP) 的文件,设置组 ID 位表示强制文件/记录锁定。目录上的粘滞位 (S_ISVTX) 表示只有文件的拥有者、目录的拥有者以及特权进程才能重命名或删除该目录中的文件。

POSIX 不描述 S_IFMTS_IFSOCKS_IFLNKS_IFREGS_IFBLKS_IFDIRS_IFCHRS_IFIFOS_ISVTX 位,而是要求使用宏 S_ISDIR() 等。S_ISLNK()S_ISSOCK() 宏不在 POSIX.1-1996 中,但都存在于 POSIX.1-2001 中;前者来自 SVID 4,后者来自 SUSv2。

其他系统 - 在各种系统中使用过的(或正在使用过的)值

十六进制 名称 ls 八进制 描述
f000 S_IFMT 170000 文件类型的掩码
0000 000000 SCO 停用 inode;BSD 未知类型;SVID-v2 和 XPG2 对于普通文件都使用 0 和 0100000
1000 S_IFIFO p| 010000 FIFO(命名管道)
2000 S_IFCHR c 020000 字符特殊(V7)
3000 S_IFMPC 030000 多路复用字符特殊(V7)
4000 S_IFDIR d/ 040000 目录(V7)
5000 S_IFNAM 050000 XENIX 命名特殊文件,具有两种子类型,由 st_rdev 值 1、2 区分
0001 S_INSEM s 000001 XENIX 信号量,IFNAM 的子类型
0002 S_INSHD m 000002 XENIX 共享数据,IFNAM 的子类型
6000 S_IFBLK b 060000 块特殊(V7)
7000 S_IFMPB 070000 多路复用块特殊(V7)
8000 S_IFREG - 100000 普通(V7)
9000 S_IFCMP 110000 VxFS 压缩
9000 S_IFNWK n 110000 网络特殊(HP-UX)
a000 S_IFLNK l@ 120000 符号链接(BSD)
b000 S_IFSHAD 130000 Solaris 阴影 inode,用于 ACL(用户空间不可见)
c000 S_IFSOCK s= 140000 套接字(BSD;在 VxFS 上也称为“S_IFSOC”)
d000 S_IFDOOR D> 150000 Solaris 门
e000 S_IFWHT w% 160000 BSD whiteout(不用于 inode)
0200 S_ISVTX 001000 粘滞位:即使在使用后也要保存交换文本(V7)保留(SVID-v2)。在非目录上:不要缓存此文件(SunOS)。在目录上:限制删除标志(SVID-v4.2)
0400 S_ISGID 002000 执行时设置组 ID(V7)对于目录:使用 BSD 语义来传播 GID
0400 S_ENFMT 002000 SysV 文件锁定执行(与 S_ISGID 共享)
0800 S_ISUID 004000 执行时设置用户 ID(V7)
0800 S_CDF 004000 目录是上下文相关文件(HP-UX)

粘滞命令出现在版本 32V AT&T UNIX 中。

成员类型

[编辑 | 编辑源代码]

<sys/stat.h> 头文件中定义的数据类型包括

struct stat {
  dev_t     st_dev;     /* ID of device containing file */
  ino_t     st_ino;     /* inode number */
  mode_t    st_mode;    /* protection */
  nlink_t   st_nlink;   /* number of hard links */
  uid_t     st_uid;     /* user ID of owner */
  gid_t     st_gid;     /* group ID of owner */
  dev_t     st_rdev;    /* device ID (if special file) */
  off_t     st_size;    /* total size, in bytes */
  blksize_t st_blksize; /* blocksize for file system I/O */
  blkcnt_t  st_blocks;  /* number of blocks allocated */
  time_t    st_atime;   /* time of last access */
  time_t    st_mtime;   /* time of last modification */
  time_t    st_ctime;   /* time of last status change */
};

<sys/stat.h> 的一个简短示例

/**************************************************************
 abstract ls meaning
 **************************************************************/
#include <stdio.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>

int main(int argc, char **argv)
{
  struct stat  file_stat;

  while (argc-- > 1)
    {
      if (lstat(argv[argc], &file_stat) == -1)
        fprintf(stderr, "%s\n", strerror(errno));
      else
        {
          fprintf(stdout, "Links\tUid\tGid\tSize\tName\n");
          fprintf(stdout, "%u\t%u\t%u\t%u\t%s\n", file_stat.st_nlink,
                  file_stat.st_uid, file_stat.st_gid, file_stat.st_size,
                  argv[argc]);
        }
    }
  return 0;
}

将源代码放在一个文件(main.c)中,并编译它

 gcc main.c -o test

现在,要运行,请键入

 ./test main.c
 ./test *

参考资料

[编辑 | 编辑源代码]
华夏公益教科书