stat() - Unix,Linux系统调用
广告
名称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_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) 表示只有文件的所有者、目录的所有者和特权进程才能重命名或删除该目录中的文件。 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_blocks和st_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 | 八进制 | 描述 |
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 用于 ACL 的影子 inode(用户空间看不到) |
c000 | S_IFSOCK | s= | 140000 | 套接字(BSD;在 VxFS 上也称为“S_IFSOC”) |
d000 | S_IFDOOR | D> | 150000 | Solaris 门 |
e000 | S_IFWHT | w% | 160000 | BSD 白洞(不用于 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 版本中。 参见
广告
|