stat() - Unix,Linux 系统调用
Tutorials Point


  Unix 初学者指南
  Unix Shell 编程
  高级 Unix
  Unix 有用参考
  Unix 有用资源
  精选阅读

版权所有 © 2014 tutorialspoint



  首页     参考     讨论论坛     关于 TP  

stat() - Unix,Linux 系统调用


previous next AddThis Social Bookmark Button

广告

名称

stat、fstat、lstat - 获取文件状态

语法

#include <sys/types.h> 
#include <sys/stat.h> 
#include <unistd.h> 

int stat(const char *path, struct stat *buf); int fstat(int filedes, struct stat *buf); int lstat(const char *path, struct stat *buf);

描述

这些函数返回有关文件的信息。文件本身不需要任何权限,但是 - 在 stat() 和 lstat() 的情况下 - 需要对通往文件的 path 中的所有目录具有执行(搜索)权限。

stat() 统计 path 指向的文件并填充 buflstat() 与 stat() 相同,除了如果 path 是符号链接,则会统计链接本身,而不是它所引用的文件。

fstat() 与 stat() 相同,除了要统计的文件由文件描述符 filedes 指定。

所有这些系统调用都返回一个 stat 结构,其中包含以下字段

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 filesystem 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 */
};

st_dev 字段描述了此文件所在的设备。

st_rdev 字段描述了此文件(inode)表示的设备。

st_size 字段以字节为单位给出文件(如果它是常规文件或符号链接)的大小。符号链接的大小是它包含的路径名的长度,不包括尾随的空字节。

st_blocks 字段指示分配给文件的数据块数量,以 512 字节为单位。(这可能小于 st_size/512,例如,当文件有空洞时。)

st_blksize 字段给出用于高效文件系统 I/O 的“首选”块大小。(以较小的块写入文件可能会导致效率低下的读-修改-重写。)

并非所有 Linux 文件系统都实现了所有时间字段。某些文件系统类型允许以不会导致更新 st_atime 字段的方式进行挂载。(请参阅 mount(8) 中的“noatime”。)

st_atime 字段会因文件访问而更改,例如,由 execve(2)、mknod(2)、pipe(2)、utime(2) 和 read(2)(超过零字节)更改。其他例程,如 mmap(2),可能会或可能不会更新 st_atime

st_mtime 字段会因文件修改而更改,例如,由 mknod(2)、truncate(2)、utime(2) 和 write(2)(超过零字节)更改。此外,目录的 st_mtime 会因该目录中文件的创建或删除而更改。st_mtime 字段不会因所有者、组、硬链接计数或模式的更改而更改。

st_ctime 字段会因写入或设置 inode 信息(即所有者、组、链接计数、模式等)而更改。

以下 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_IFMT0170000文件类型位字段的位掩码
S_IFSOCK0140000套接字
S_IFLNK0120000符号链接
S_IFREG0100000常规文件
S_IFBLK0060000块设备
S_IFDIR0040000目录
S_IFCHR0020000字符设备
S_IFIFO0010000FIFO
S_ISUID0004000设置 UID 位
S_ISGID0002000设置组 ID 位(见下文)
S_ISVTX0001000粘滞位(见下文)
S_IRWXU00700文件所有者权限的掩码
S_IRUSR00400所有者具有读取权限
S_IWUSR00200所有者具有写入权限
S_IXUSR00100所有者具有执行权限
S_IRWXG00070组权限的掩码
S_IRGRP00040组具有读取权限
S_IWGRP00020组具有写入权限
S_IXGRP00010组具有执行权限
S_IRWXO00007其他用户(不在组中)的权限掩码
S_IROTH00004其他用户具有读取权限
S_IWOTH00002其他用户具有写入权限
S_IXOTH00001其他用户具有执行权限

设置组 ID 位 (S_ISGID) 有几个特殊用途。对于目录,它指示应为该目录使用 BSD 语义:在其中创建的文件将从目录继承其组 ID,而不是从创建进程的有效组 ID 继承,并且在其中创建的目录也将设置 S_ISGID 位。对于未设置组执行位 (S_IXGRP) 的文件,设置组 ID 位表示强制文件/记录锁定。

目录上的“粘滞”位 (S_ISVTX) 表示只有文件的所有者、目录的所有者以及特权进程才能重命名或删除该目录中的文件。

Linux 说明

自内核 2.5.48 以来,stat 结构支持三个文件时间戳字段的纳秒分辨率。如果定义了 _BSD_SOURCE 或 _SVID_SOURCE 特性测试宏,则 Glibc 使用 st_atim.tv_nsec 形式的名称公开每个字段的纳秒分量,或者如果未定义这些宏中的任何一个,则使用 st_atimensec 形式的名称公开。在不支持亚秒级时间戳的文件系统上,这些纳秒字段将返回 0 值。

对于 /proc 目录下的大多数文件,stat() 不会在 st_size 字段中返回文件大小;而是将该字段返回 0 值。

返回值

成功时,返回零。错误时,返回 -1,并且 errno 被相应地设置。

错误

标签描述
EACCES 拒绝搜索 path 的路径前缀中的某个目录的权限。(另请参阅 path_resolution(2)。)
EBADF filedes 无效。
EFAULT 错误地址。
ELOOP 在遍历路径时遇到太多符号链接。
ENAMETOOLONG 文件名太长。
ENOENT path 的某个组件不存在,或者路径为空字符串。
ENOMEM 内存不足(即内核内存)。
ENOTDIR 路径的某个组件不是目录。

符合标准

这些系统调用符合 SVr4、4.3BSD、POSIX.1-2001。

st_blocksst_blksize 字段的使用可能不太便携。(它们是在 BSD 中引入的。解释在系统之间以及当涉及 NFS 挂载时可能在单个系统上有所不同。)

POSIX 没有描述 S_IFMT、S_IFSOCK、S_IFLNK、S_IFREG、S_IFBLK、S_IFDIR、S_IFCHR、S_IFIFO、S_ISVTX 位,而是要求使用 S_ISDIR() 等宏。S_ISLNK 和 S_ISSOCK 宏不在 POSIX.1-1996 中,但都存在于 POSIX.1-2001 中;前者来自 SVID 4,后者来自 SUSv2。

Unix V7(以及后续系统)有 S_IREAD、S_IWRITE、S_IEXEC,而 POSIX 规定了同义词 S_IRUSR、S_IWUSR、S_IXUSR。

其他系统

各种系统上已使用(或正在使用)的值

十六进制名称ls八进制描述
f000S_IFMT 170000文件类型的掩码
0000  000000SCO 停用 inode,BSD 未知类型
    SVID-v2 和 XPG2 对普通文件都使用 0 和 0100000
1000S_IFIFOp|010000FIFO(命名管道)
2000S_IFCHRc020000字符特殊(V7)
3000S_IFMPC 030000多路复用字符特殊(V7)
4000S_IFDIRd/040000目录(V7)
5000S_IFNAM 050000XENIX 命名特殊文件
    有两个子类型,由 st_rdev 值 1、2 区分
0001S_INSEMs000001XENIX IFNAM 的信号量子类型
0002S_INSHDm000002XENIX IFNAM 的共享数据子类型
6000S_IFBLKb060000块特殊(V7)
7000S_IFMPB 070000多路复用块特殊(V7)
8000S_IFREG-100000常规(V7)
9000S_IFCMP 110000VxFS 压缩
9000S_IFNWKn110000网络特殊(HP-UX)
a000S_IFLNKl@120000符号链接(BSD)
b000S_IFSHAD 130000Solaris ACL 的影子 inode(用户空间看不到)
c000S_IFSOCKs=140000套接字(BSD;VxFS 上也称为“S_IFSOC”)
d000S_IFDOORD>150000Solaris 门
e000S_IFWHTw%160000BSD 覆盖(不用于 inode)
0200S_ISVTX 001000“粘滞位”:即使在使用后也保存交换的文本(V7)
    保留(SVID-v2)
    在非目录上:不要缓存此文件(SunOS)
    在目录上:受限删除标志(SVID-v4.2)
0400S_ISGID 002000执行时设置组 ID(V7)
    对于目录:使用 BSD 语义传播 GID
0400S_ENFMT 002000SysV 文件锁定执行(与 S_ISGID 共享)
0800S_ISUID 004000执行时设置用户 ID(V7)
0800S_CDF 004000目录是上下文相关文件(HP-UX)

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

参见



previous next Printer Friendly

广告


  

广告



广告