参考apue:
#include <sys/stat> /* 头文件 */ 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 fstat(int fd, const char *restrict pathname, struct stat *restrict buf, int flag); /* 函数成功返回0,失败返回-1; */ struct stat { /* stat结构体 */ mode_t st_mode;//文件对应的模式,文件,目录,权限等 ino_t st_ino;//i-node节点号 dev_t st_dev;//设备号码 dev_t st_rdev;//特殊设备号码 nlink_t st_nlink;//文件的硬链接数 uid_t st_uid;//文件所有者 gid_t st_gid;//文件所有者对应的组 off_t st_size;//普通文件,对应的文件字节数 struct timespec st_atime;//文件最后被访问的时间 struct timespec st_mtime;//文件内容最后被修改的时间 struct timespec st_ctime;//文件状态(属性)改变时间 blksize_t st_blksize;//文件内容对应的块大小 blkcnt_t st_blocks;//文件内容对应的块数量 }
分析函数:
函数根据给出的pathname返回与文件相关的信息buf。
stat()函数参数pathname使用直接路径;
fstat()函数参数fd使用文件描述符号;
lstat()类似stat(),但是当pathnam为符号链接即软连接时,返回软连接信息;
fstatat()函数当pathname为相对路径时,函数根据文件描述符号fd进行信息返回,当pathname为绝对路径时,文件描述符号被忽略,而且当flag = AT_SYMLINK_NOFOLLOW时,不会跟随符号链接,直接返回符号链接信息。
1 #include <sys/stat.h> 2 #include <stdio.h> 3 4 int main() 5 { 6 const char* pathname = "/home/huangzijian/projects/c/pathname.txt"; 7 struct stat buf; 8 if((stat(pathname, &buf)) == -1) { 9 return -1; 10 } 11 printf("%d\n", (int)buf.st_mode); 12 return 0; 13 } 14 15 /* 16 输出:33188 17 */
pathname.txt文件权限为644,而上面代码输出33188,八进制为0100644,取低3位。但是为什么?
先前所描述的st_mode表示文件类型和文件权限,则定义下列数种情况:
S_IFMT 0170000 文件类型的位遮罩
S_IFSOCK 0140000 socket
S_IFLNK 0120000 符号链接(symbolic link)
S_IFREG 0100000 一般文件
S_IFBLK 0060000 区块装置(block device)
S_IFDIR 0040000 目录
S_IFCHR 0020000 字符装置(character device)
S_IFFIFO 0010000 管道文件(fifo)
S_ISUID 0004000 文件的(set user-id on execution) 位
S_ISGID 0002000 文件的(set group-id on execution) 位
S_ISVTC 0001000 文件的(sticky) 位
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 文件其他用户具有执行权限
注:100644,1位于第六位,是一般文件。权限为644。
1 #include <sys/stat.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 5 int main() 6 { 7 char *pathname1 = "/home/huangzijian/projects/c/pathname.txt"; 8 char *pathname2 = "/home/huangzijian/projects/c/pathname.sl"; 9 struct stat buf1, buf2; 10 11 stat(pathname1, &buf1); 12 lstat(pathname2, &buf2); 13 14 if(S_ISREG(buf1.st_mode)) { 15 printf("一般文件\n"); 16 } 17 18 if(S_ISLNK(buf2.st_mode)) { 19 printf("符号链接\n"); 20 } 21 22 return 0; 23 } 24
注:lstat()可以打开非符号链接,此时如同stat()函数。
根据st_mode进行判断:
S_ISREG(m) 一般文件
S_ISDIR(m) 目录
S_ISCHR(m) 字符装置
S_ISBLK(m) 块装置
S_ISFIFO(m) FIFO管道
S_ISLNK(m) 符号链接
S_ISSOCK(m) socket
错误代码:
EACCES 搜索存取文件被拒绝。
EBADF 文件描述fd符号错误。
EFAULT 错误地址。
ELOOP 打开文件具有过多符号链接。
ENAMETOOLONG 文件名过长。
ENOENT 路径不存在或者为空。
ENOMEM 核心内存不足
ENOTDIR 路径的前缀不存在
EOVERFLOW 内存溢出