糖尿病康复,内容丰富有趣,生活中的好帮手!
糖尿病康复 > stat函数(stat fstat lstat)

stat函数(stat fstat lstat)

时间:2020-03-04 20:48:22

相关推荐

stat函数(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 fd, struct stat *buf);

fstat函数与stat函数的功能一样,只是第一个形参是文件描述符。

int lstat(const char *path, struct stat *buf);

lstat函数的形参跟stat函数的形参一样。其功能也跟stat函数功能一样,仅有一点不同:stat函数是穿透(追踪)函数,即对软链接文件进行操作时,操作的是链接到的那一个文件,不是软链接文件本身;而lstat函数是不穿透(不追踪)函数,对软链接文件进行操作时,操作的是软链接文件本身。

以上三个函数:成功返回0,失败返回-1,并且将详细错误信息赋值给errno全局变量。

其它Linux系统函数类似,带l表示不追踪,不带l表示追踪(穿透)。如:ls –l命令查看的文件属性,是不追踪(不穿透)的;rm删除文件时,是不追踪的;Vi和Vim是穿透的;对于穿透的命令,是无法判断文件是不是软链接文件,比如ls –l命令,其是不穿透的,因此可以判断是否是软链接文件;如果是用stat函数实现的ls –l命令,则是穿透的,对于查看原文件和链接文件的属性是一样的,无法区别两者,因此可以考虑用lstat函数来实现ls –l命令的功能。

注意:创建软链接最好用绝对路径 ln –s 原文件 软链接文件(采用绝对路径)

statlstatfstat函数中struct stat类型的说明:

struct stat {

dev_t st_dev; /* 文件的设备编号 */

ino_t st_ino; /*索引结点编号*/

mode_t st_mode; /*文件类型和权限*/

nlink_t st_nlink; /*硬链接数*/

uid_t st_uid; /*用户ID*/

gid_t st_gid; /*ID*/

dev_t st_rdev; /* 设备类型(若此文件为设备文件,则为设备编号*/

off_t st_size; /*文件大小*/

blksize_t st_blksize; /*文件系统的I/O缓冲区大小*/

blkcnt_t st_blocks; /*块数*/

time_t st_atime; /* 访问时间 */

time_t st_mtime; /* 修改时间 */

time_t st_ctime; /*更改时间*/

}; //标红为重点内容

struct stat结构体位于inode(索引结点)中,但是其内部不包含文件名。文件名位于位于文件的目录项dentry中(即简化的FCB),其包含文件名和inode编号。通过denty的inode编号可以找到inode,进一步找到文件本身。硬链接就是denty(目录项)。

上述结构体中,对st_mode成员做一个详细的介绍:

mode_t st_mode; /* 文件类型和权限*/

st_mode变量(mode_t类型):该变量占 2byte共16位,为16位的整型值。用于储存文件类型和权限。 如下图所示:

每一位均为二进制数。r代表4,即100;w代表2,即010;x代表1,即001。由于总共16位二进制数,因此需要6位8进制数来进行表示,其中8进制数以0开头,共7位。

其他人权限(0~2位)。读权限:0000004,在所给函数头文件中进行了宏定义为:S_IROTH;写:0000002,S_IWOTH;执行:0000001,S_IXOTH。 掩码为:0000007,S_IRWXO掩码的作用:st_mode & 掩码 就可以过滤st_mode中除其他人权限以外的信息,所得结果直接是其他人的权限信息,下面原理相同。

所属组权限(3~5位)。读权限:0000040, S_IRGRP;写:0000020,S_IWGRP;执行:0000010,S_IXGRP。 掩码为:0000070,S_IRWXG。

所属主权限(6~8位)。读权限:0000400, S_IRUSR;写:0000200,S_IWUSR;执行:0000100,S_IXUSR。 掩码为:0000700,S_IRWXU。

特殊权限位(9~11位)。SUID:0004000, S_ISUID;SGID:0002000,S_ISGID;SBIT:0001000,S_ISVTX。//特殊权限位很少用

文件类型(12~15位,共7种类型文件)。套接字(socket)文件s:0140000,S_IFSOCK;链接文件(软链接)l:0120000,S_IFLNK;普通文件-:0100000,S_IFREG;块设备文件b:0060000,S_IFBLK;目录文件d:0040000,S_IFDIR;字符设备文件c:0020000,S_IFCHR;管道文件p:0010000,S_IFIFO。 掩码:0170000 作用一样,st_mode & 掩码 的结果与七种类型的宏相比较,就可以判断是哪一种文件。

强调一下特殊权限位SBIT(粘滞位)的功能:1.对目录设置粘滞位,则该目录内的文件只能被文件所有者、超级用户和目录所有者这三类用户删除,其他用户都没有删除的权限;2.对文件设置了粘滞位,那么在内存资源十分紧张的情况下,也不会把该文件放回到磁盘上。如磁盘的对换区SWAP,当内存紧张,优先级别低的进程会被暂时放回到对换区中,但是一旦设置了粘滞位,则不会放回磁盘,依然处于内存。

下面是说明stat函数的使用的代码:

//运用stat函数实现查看文件大小属性的功能

[root@localhost work]# vim statuse.c

#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>int main( int argc,char *argv[ ] ) //命令行参数{if( argc < 2 )printf("./statuse filename1 filename2 ...\n");struct stat zsx;int ret;int i=1;for( i=1;i<argc;i++ ){ret = stat( argv[i],&zsx); //stat函数获取文件的属性,穿透的if( ret == -1 ){perror("stat filename");exit(1);}int size = (int)zsx.st_size; //注意,必须强制转换,后者变量是off_t类型printf("%s%d\n",argv[i],size);}return 0;}

[root@localhost work]# gcc -pipe -ggdb3 -pedantic -Wall statuse.c -o statuse

[root@localhost work]# ls

english.txt ls-l.c stat.c statuse statuse.c

[root@localhost work]# ./statuse english.txt ls-l.c stat.c statuse statuse.c

english.txt109055

ls-l.c 2204

stat.c 416

statuse 57468

statuse.c 535

[root@localhost work]# ll english.txt

-rwxrwxrwx. 1 root root109055Mar 19 10:30 english.txt

//运用stat函数实现ls –l命令的功能

#include <stdio.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <stdlib.h>#include <time.h>#include <pwd.h>#include <grp.h>int main(int argc, char* argv[]){if(argc < 2)int main(int argc, char* argv[]){if(argc < 2){printf("./a.out filename\n");exit(1);}struct stat st;int ret = stat(argv[1], &st);if(ret == -1){perror("stat");exit(1);}// 存储文件类型和访问权限char perms[11] = {0};// 判断文件类型switch(st.st_mode & S_IFMT){case S_IFLNK:perms[0] = 'l';break;case S_IFDIR:perms[0] = 'd';break;case S_IFREG:perms[0] = '-';break;case S_IFBLK:perms[0] = 'b';break;case S_IFCHR:perms[0] = 'c';break;case S_IFSOCK:perms[0] = 's';break;case S_IFIFO:perms[0] = 'p';break;default:perms[0] = '?';break;}// 判断文件的访问权限// 文件所有者perms[1] = (st.st_mode & S_IRUSR) ? 'r' : '-';perms[2] = (st.st_mode & S_IWUSR) ? 'w' : '-';perms[3] = (st.st_mode & S_IXUSR) ? 'x' : '-';// 文件所属组perms[4] = (st.st_mode & S_IRGRP) ? 'r' : '-';perms[5] = (st.st_mode & S_IWGRP) ? 'w' : '-';perms[6] = (st.st_mode & S_IXGRP) ? 'x' : '-';// 其他人perms[7] = (st.st_mode & S_IROTH) ? 'r' : '-';perms[8] = (st.st_mode & S_IWOTH) ? 'w' : '-';perms[9] = (st.st_mode & S_IXOTH) ? 'x' : '-';// 硬链接计数int linkNum = st.st_nlink;// 文件所有者char* fileUser = getpwuid(st.st_uid)->pw_name;// 文件所属组char* fileGrp = getgrgid(st.st_gid)->gr_name;// 文件大小int fileSize = (int)st.st_size;// 修改时间char* time = ctime(&st.st_mtime);char mtime[512] = {0};strncpy(mtime, time, strlen(time)-1);char buf[1024];sprintf(buf, "%s %d %s %s %d %s %s", perms, linkNum, fileUser, fileGrp, fileSize, mtime, argv[1]);printf("%s\n", buf);return 0;}

如果觉得《stat函数(stat fstat lstat)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。