4.2 stat, fstat, fstatat, lstat
int stat(const char *restrict pathname, struct stat *restrict buf);
int fstat(int fd, struct stat buf);
int lstat(const char* restrict pathname, struct stat *restrict buf);
int fstatat(int fd, const char *restrict pathname, struct stat *restrict buf, int flag);
- stat: 返回 pathname 文件的信息结构。
- fstat: 返回 fd 文件描述符的文件信息。
- lstat: 和 stat 类似,但如果 pathname 是一个符号链接,lstat 返回符号链接的有关信息,而不是符号链接指向的文件信息。
- fstatat 返回相对于 fd 文件描述符 pathname 路径名的文件信息。flag AT_SYMLINK_NOFOLLOW 表示不跟随符号链接展开。
stat 结构体不同系统实现可能不同:
struct stat {
dev_t st_dev; /* [XSI] ID of device containing file */ \
mode_t st_mode; /* [XSI] Mode of file (see below) */ \
nlink_t st_nlink; /* [XSI] Number of hard links */ \
__darwin_ino64_t st_ino; /* [XSI] File serial number */ \
uid_t st_uid; /* [XSI] User ID of the file */ \
gid_t st_gid; /* [XSI] Group ID of the file */ \
dev_t st_rdev; /* [XSI] Device ID */ \
__DARWIN_STRUCT_STAT64_TIMES \
off_t st_size; /* [XSI] file size, in bytes */ \
blkcnt_t st_blocks; /* [XSI] blocks allocated for file */ \
blksize_t st_blksize; /* [XSI] optimal blocksize for I/O */ \
__uint32_t st_flags; /* user defined flags for file */ \
__uint32_t st_gen; /* file generation number */ \
__int32_t st_lspare; /* RESERVED: DO NOT USE! */ \
__int64_t st_qspare[2]; /* RESERVED: DO NOT USE! */ \
}
4.3 文件类型
- 普通文件
- 目录文件,只有内核可以直接写目录文件。
- 块特殊文件 block special file. 提供对设备(如磁盘)带缓冲的访问。
- 字符特殊文件 character special file. 提供对设备不带缓冲的访问,系统中的所有设备要么是字符特殊文件,要么是块特殊文件
- FIFO,有时也叫做命名管道 named pipe。
- 套接字 socket
- 符号链接 symbolic link
文件类型信息包含在 stat 结构的 st_mode 成员中,可以用下列的宏确定文件类型,这些宏的参数都是 stat 中的 st_mode。
S_ISREG() // 普通文件
S_ISDIR() // 目录文件
S_ISCHR() // 字符特殊文件
S_ISBLK() // 块特殊文件
S_ISFIFO() // FIFO
S_ISLINK() // 符号链接
S_ISSOCK() // 套接字
4.4 设置用户 ID 和设置组 ID
// TODO:
4.5 文件访问权限
每个文件有 9 个访问权限位:
- S_IRUSR 用户读
- S_IWUSR 用户写
- S_IXUSR 用户执行
- S_IRGRP 组读
- S_IWGRP 组写
- S_IXGRP 组执行
- S_IROTH 其他读
- S_IWOTH 其他写
- S_IXOTH 其他执行
4.6 新文件和目录的所有权
// TODO:
4.7 函数 access 和 faccessat
当用 open 打开一个文件时,内核以进程的有效用户 ID 和有效组 ID 为基础执行其访问权限测试。
而 access 和 faccessat 函数按照实际用户 ID 和实际组 ID 进行访问权限测试。
int access(const char *pathname, int mode);
int faccessat(int fd, const char *pathname, int mode, int flag);
如果测试文件已经存在,mode 为 F_OK, 否则 mode 为 R_OK, W_OK, X_OK 或者他们的或。
faccessat 计算相对于打开目录 (fd) 的 pathname。
4.8 umask
umask 为进程设置文件模式创建屏蔽字,并返回之前的值。
umask 设置的权限位,再调用类似 create 函数创建文件,会自动屏蔽该权限位
mode_t umask(mode_t cmask);
其中 cmask 为 4.5 中列出的 9 个常量的若干位。
4.9 函数 chmod, fchmod 和 fchmodat
这三个函数可以改变现有文件的访问权限。
int chmod(const char *pathname, mode_t mode);
int fchmod(int fd, mode_t mode);
int fchmodat(int fd, const char *pathname, mode_t mode, int flag);
其中 mode 为 4.5 中的 9 个,加上
- S_ISUID 执行时设置用户 ID
- S_ISGID 执行时设置组 ID
- S_ISVTX 保存正文 (现代系统用不上了)
- S_IRWXU 用户读 + 写 + 执行
- S_IRWXG 组读 + 写 + 执行
- S_IRWXO 其他读 + 写 + 执行
4.10 黏着位
4.11 函数 chown, fchown, fchownat 和 lchown
用于更改文件的用户 ID 和组 ID.
int chown(const char *pathname, uid_t owner, gid_t group);
int fchown(int fd, uid_t owner, gid_t group);
int fchownat(int fd, const char *pathname, uid_t owner, gid_t group, int flag);
int lchown(const char *pathname, uid_t owner, gid_t group);
lchown 和 fchownat 会修改符号链接本身的所有者,chown 和 fchown 只会改变符号链接指向文件的所有者。
4.12 文件长度
stat 的 st_size 成员。只对普通文件,目录文件和符号链接有意义。
4.13 文件截断
int truncate(const char *pathname, off_t length);
int ftruncate(int fd, off_t length);
4.14 文件系统
skip