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 指向的文件的状态并填充 buf

lstat() 与 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)
    对于目录:对 GID 的传播使用 BSD 语义
0400S_ENFMT 002000SysV 文件锁定执行(与 S_ISGID 共享)
0800S_ISUID 004000执行时设置用户 ID(V7)
0800S_CDF 004000目录是上下文相关文件(HP-UX)

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

另请参阅



previous next Printer Friendly

广告


  

广告



广告