查询man 2 stat
SYNOPSIS
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *path, struct stat *buf);
//stat() stats the file pointed to by path and fills in buf.
int fstat(int fd, struct stat *buf);
//fd是文件描述符
int lstat(const char *path, struct stat *buf);
//当文件是一个符号链接时,lstat返回的是该符号链接本身的信息
DESCRIPTION
1 struct stat {
2 dev_t st_dev; /* ID of device containing file 文件的设备编号*/
3 ino_t st_ino; /* inode number 引索节点*/
4 mode_t st_mode; /* protection 文件的类型和存取的权限*/
5 nlink_t st_nlink; /* number of hard links 硬连接数*/
6 uid_t st_uid; /* user ID of owner 用户ID*/
7 gid_t st_gid; /* group ID of owner 用户组ID*/
8 dev_t st_rdev; /* device ID (if special file) . The st_rdev field describes the device that this file (inode) represents.
如果这个是设备文件,那么它将描述的是在本设备文件(节点)的设备编号 */
9 off_t st_size; /* total size, in bytes 文件大小*/
10 blksize_t st_blksize; /* blocksize for file system I/O 块大小*/
11 blkcnt_t st_blocks; /* number of 512B blocks allocated 块数*/
12 time_t st_atime; /* time of last access 最后访问时间*/
13 time_t st_mtime; /* time of last modification 最后修改时间*/
14 time_t st_ctime; /* time of last status change . changed by writing or by setting inode information
最后一次被写、属性修改的时间*/
15 };
宏定义:
the st_mode field:
S_ISREG(m) is it a regular file? 是否为普通文件
S_ISDIR(m) directory? 是否为目录
S_ISCHR(m) character device? 是否为字符设备
S_ISBLK(m) block device? 是否为块设备
S_ISFIFO(m) FIFO (named pipe)? 是否为管道
S_ISLNK(m) symbolic link? (Not in POSIX.1-1996.) 是否为软链接
S_ISSOCK(m) socket? (Not in POSIX.1-1996.) 是否为套接字
1 S_IFMT 0170000 bit mask for the file type bit fields 2 S_IFSOCK 0140000 socket 3 S_IFLNK 0120000 symbolic link 4 S_IFREG 0100000 regular file 5 S_IFBLK 0060000 block device 6 S_IFDIR 0040000 directory 7 S_IFCHR 0020000 character device 8 S_IFIFO 0010000 FIFO 9 S_ISUID 0004000 set UID bit 10 S_ISGID 0002000 set-group-ID bit (see below) 11 S_ISVTX 0001000 sticky bit (see below) 12 S_IRWXU 00700 mask for file owner permissions 13 S_IRUSR 00400 owner has read permission 14 S_IWUSR 00200 owner has write permission 15 S_IXUSR 00100 owner has execute permission 16 S_IRWXG 00070 mask for group permissions 17 S_IRGRP 00040 group has read permission 18 S_IWGRP 00020 group has write permission 19 S_IXGRP 00010 group has execute permission 20 S_IRWXO 00007 mask for permissions for others (not in group) 21 S_IROTH 00004 others have read permission 22 S_IWOTH 00002 others have write permission 23 S_IXOTH 00001 others have execute permission
下面是用stat函数写了一个 ll (shell)
1 #include<stdio.h> 2 #include<sys/types.h> 3 #include<sys/stat.h> 4 #include<unistd.h> 5 #include<string.h> 6 #include<pwd.h> 7 #include<grp.h> 8 #include<time.h> 9 #include<stdlib.h> 10 #include<dirent.h> 11 12 #define BUF_SIZE 11 //宏定义大小和错误值 13 #define GET_OK 0 14 #define GET_ERR -1 15 16 17 int GetFileType(char *buf,mode_t tMode); //文件类型 18 int GetFilePermission(char *buf,mode_t tMode); //文件权限 19 20 21 int main() 22 { 23 //open dir 24 DIR *dir=opendir("."); 25 if(NULL == dir) 26 { 27 return -1; 28 } 29 //read dir 30 struct dirent *pItem = NULL; //初始化 31 struct stat stInfo; 32 char buf[BUF_SIZE] = {0}; 33 struct passwd *pPwd = NULL; 34 struct group *pGroup = NULL; 35 36 while(NULL !=(pItem=readdir(dir))) 37 { 38 memset(&stInfo,0,sizeof(struct stat)); 39 memset(buf,0,BUF_SIZE); 40 if(0 != stat(pItem->d_name,&stInfo)) //获取stat结构体 41 { 42 continue; 43 } 44 // mode 45 if(GET_OK != GetFileType(buf,stInfo.st_mode)) 46 { 47 continue; 48 } 49 50 if(GET_OK != GetFilePermission(buf,stInfo.st_mode)) 51 { 52 continue; 53 } 54 55 if(NULL == (pPwd = getpwuid(stInfo.st_uid))) 56 { 57 continue; 58 } 59 if(NULL == (pGroup = getgrgid(stInfo.st_gid))) 60 { 61 continue; 62 } 63 printf("%s %d %s %s %ld %s %s\r\n",buf,stInfo.st_nlink,pPwd->pw_name,pGroup->gr_name,stInfo.st_size,ctime(&stInfo.st_atime),pItem->d_name); 64 } 65 return 0; 66 } 67 68 int GetFileType(char *buf,mode_t tMode) 69 { 70 if(NULL == buf) 71 { 72 return GET_ERR; 73 } 74 buf[0]='-'; 75 if(S_ISREG(tMode)) buf[0]='-'; 76 if(S_ISDIR(tMode)) buf[0]='d'; 77 return GET_OK; 78 } 79 80 81 82 int GetFilePermission(char *buf,mode_t tMode) 83 { 84 if(NULL == buf) 85 { 86 return GET_ERR; 87 } 88 89 memset(buf+1,'-',BUF_SIZE-2); //前一位已经被编写过了,移动 90 if(tMode & S_IRUSR) buf[1]='r'; //测试权限,最上面有宏定义可以看出,可以点+号打开 91 if(tMode & S_IWUSR) buf[2]='w'; 92 if(tMode & S_IXUSR) buf[3]='x'; 93 94 if(tMode & S_IRGRP) buf[4]='r'; 95 if(tMode & S_IWGRP) buf[5]='w'; 96 if(tMode & S_IXGRP) buf[6]='x'; 97 98 if(tMode & S_IROTH) buf[7]='r'; 99 if(tMode & S_IWOTH) buf[8]='w'; 100 if(tMode & S_IXOTH) buf[9]='x'; 101 102 return GET_OK; 103 }