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)
    对于目录:使用 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

广告


  

广告



广告