stat/lstat/fstat: 完成ls -l的功能

穿透

穿透软链接:直接查看[原始文件]的状态信息
不穿透(追踪)软链接:查看的是当前软连接文件的信息


在这里插入图片描述

int stat(const char *pathname, struct stat *buf);
int lstat(const char *pathname, struct stat *buf);
int fstat(int fd, struct stat *buf);  //参数fd

lstat
lstat和stat的区别:lstat不穿透,stat穿透
stat

int stat(const char *restrict path, struct stat *restrict buf);
返回值:
	成功:0
	失败:-1,errno被设置为合适的值
  struct stat {
      dev_t     st_dev;  /* ID of device containing file */文件设备编号
      ino_t     st_ino;  /* inode number */节点
      mode_t    st_mode;  文件类型和存取权限
      nlink_t   st_nlink;/* number of hard links */硬链接数
      uid_t     st_uid;   用户ID
      gid_t     st_gid;    组ID
      dev_t     st_rdev; /* device ID (if special file) */设备编号(if is 设备文件)
      off_t     st_size;  文件字节数(文件大小)
      blksize_t st_blksize;       /* blocksize for filesystem I/O */块大小
      blkcnt_t  st_blocks;        /* number of 512B blocks allocated */块数

      struct timespec st_atim;    /* time of last access */最后一次访问时间
      struct timespec st_mtim;  最后一次修改时间
      struct timespec st_ctim;    /* time of last status change */最后一次改变时间
  };
mode_t    st_mode;  文件类型和存取权限的解读,是16bit的整数
      文件类型  特殊权限位  User  Group  Others
占据位数  4			3		3	  3  	 3
					        gus	   rwx   rwx    rwx
0-2bit——其他人权限
  S_IROTH	00004	读权限
  S_IWOTH	00002	写权限
  S_IXOTH	00001	执行权限
  S_IRWXO	00007	掩码,过滤st_mode中除其他人权限以外的信息
3-5bit——所属组权限
  S_IRGRP	00040	读权限
  S_IWGRP	00020	写权限
  S_IXGRP	00010	执行权限
  S_IRWXG	00070	掩码,过滤st_mode中除所属组权限以外的信息
6-8bit——所有者权限
  S_IRUSR	00040	读权限
  S_IWUSR	00020	写权限
  S_IXUSR	00010	执行权限
  S_IRWXU	00070	掩码,过滤st_mode中除所有者权限以外的信息
12-15——文件类型
  S_IFSOCK	0140000套接字
  S_IFLNK	0120000符号链接(软连接)
  S_IFREG	0100000普通文件
  S_IFDIR	0040000目录
  S_IFCHR	0020000字符设备
  S_IFIFO	0010000管道
  S_IFMT	0170000掩码,过滤st_mode中除文件类型以外的信息
判断文件类型:
	(st_mode & S_IFMT)==S_IFREG  判断文件是否为普通文件
[]打印文件所有者对文件的访问权限; 判断文件是否为普通文件
int main(){ 
  struct stat st;    
  int ret=stat("test",&st);   
  if(ret==-1){       
    perror("stat fail");      
    exit(1);
  }        
  //文件大小
  printf("file size = %d\n",st.st_size);  
  //判断文件是否为普通文件     
  if((st.st_mode & S_IFMT) == S_IFREG) 
    printf("file是普通文件\n");        
  else      
    printf("file不是普通文件\n");    

  //获取文件的user的访问权限   
  printf("the user's rwx is :");       
  if(st.st_mode & S_IRUSR)    
    printf("r");     
  else      
      printf("-");   
  if(st.st_mode & S_IWUSR)    
    printf("w");     
  else      
    printf("-");     
  if(st.st_mode & S_IXUSR)    
    printf("x");     
  else      
    printf("-");     
  printf("\n");      
  return 0; 
} 

综合案例

使用lstat函数,实现ls -l

  #include <stdio.h> 
  #include <stdlib.h>
  #include <unistd.h>
   
  #include <sys/stat.h>       
  #include <sys/types.h>      
  #include <fcntl.h> 
   
  #include <string.h>
   
  #include <time.h>  
  #include <pwd.h>   
  #include <grp.h>   
   
  int main(int args,char* argv[]){     
    if(args<2){      
      perror("argc<2");       
      exit(1);       
    }       
   
    struct stat st;  
    int ret=lstat(argv[1],&st);        
    if(ret==-1){     
      perror("lstat fail");   
      exit(-1);      
    }       
   
    char perm[11]={0};  

	//判断文件类型       
    switch(st.st_mode&S_IFMT){
      case S_IFLNK:  
        perm[0]='l'; 
        break;       
      case S_IFDIR:  
        perm[0]='d'; 
        break;       
      case S_IFREG:  
        perm[0]='-'; 
        break;       
      case S_IFBLK:  
        perm[0]='b'; 
        break;       
      case S_IFCHR:  
        perm[0]='c'; 
        break;       
      case S_IFSOCK: 
        perm[0]='s'; 
        break;       
      case S_IFIFO:  
        perm[0]='p'; 
        break;       
      default:       
        perm[0]='?'; 
        break;       
    }

	//User的访问权限
    perm[1]=(st.st_mode & S_IRUSR)?'r':'-';
    perm[2]=(st.st_mode & S_IWUSR)?'w':'-';
    perm[3]=(st.st_mode & S_IXUSR)?'x':'-';
	//Group的访问权限   
    perm[4]=(st.st_mode & S_IRGRP)?'r':'-';     
    perm[5]=(st.st_mode & S_IWGRP)?'w':'-';     
    perm[6]=(st.st_mode & S_IXGRP)?'x':'-';     
	//Other的访问权限     
    perm[7]=(st.st_mode & S_IROTH)?'r':'-';     
    perm[8]=(st.st_mode & S_IWOTH)?'w':'-';     
    perm[9]=(st.st_mode & S_IXOTH)?'x':'-';     

	//硬链接数目    
    int linkNum=st.st_nlink;
    //文件所属者的name
    char* fileUser=getpwuid(st.st_uid)->pw_name; //getpwuid函数:将uid转换成uname
	//文件所属组的name
    char* fileGrp=getgrgid(st.st_gid)->gr_name;//getgrgid函数:将gid转换成gname 
	//文件大小
    int fileSize=(int)st.st_size;      
	//文件的修改时间:change time 
    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",perm,linkNum,fileUser,fileGrp,fileSize,mtime,argv[1]);
    printf("%s\n",buf);       
    return 0;        
  } 
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值