利用lstat 实现linux中ls -l功能
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
#include <grp.h>
#include <pwd.h>
//利用lstat实现ls -l功能全过程
int main(int argc,char *argv[])
{
if(argc != 2)
{
printf("User:%s <filename>\n",argv[0]);
return -1;
}
struct stat st;
lstat(argv[1],&st);//调用函数将文件信息保存在结构体上
//文件类型
if(S_ISREG(st.st_mode))//S_ISREG(st_mode)是否是一个常规文件
printf("-");
else if(S_ISDIR(st.st_mode))//S_ISDIR(st_mode)是否是一个目录
printf("d");
else if(S_ISCHR(st.st_mode))//S_ISCHR(st_mode)是否是一个字符设备
printf("c");
else if(S_ISBLK(st.st_mode))//S_ISBLK(st_mode) 是否是一个块设备
printf("b");
else if(S_ISFIFO(st.st_mode))//S_ISFIFO(st_mode)是否是一个FIFO文件
printf("p");
else if(S_ISLNK(st.st_mode))//S_ISLNK(st_mode)是否是一个连接
printf("l");
else if(S_ISSOCK(st.st_mode))//S_ISSOCK(st_mode)是否是一个SOCKET文件
printf("s");
//文件权限
char *str = "xwr-";
for(int i = 8;i >= 0;i--)
{
if(st.st_mode & 1 << i)//<<的优先级高于&
printf("%c",str[i%3]);
else
printf("%c",str[3]);
}
//硬链接数
printf(" %ld ",st.st_nlink);
//文件拥有者
printf("%s ",getpwuid(st.st_uid)->pw_name);//将st_uid得到的拥有者id号转化name
//文件所属组
printf("%s ",getgrgid(st.st_gid)->gr_name);
//文件大小
printf("%ld ",st.st_size);
//文件最后修改的时间 月份 日期 时:分
char *month[] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dev"};
struct tm *tp = localtime(&st.st_mtime);
printf("%s %d %02d:%02d ",month[tp->tm_mon],tp->tm_mday,tp->tm_hour,tp->tm_min);
//打印文件名
printf("%s\n",argv[1]);
return 0;
}
运行结果如下:
知识点补充:
S_ISLNK(st_mode) | 是否是一个连接 |
S_ISREG(st_mode) | 是否是一个常规文件 |
S_ISDIR(st_mode) | 是否是一个目录 |
S_ISCHR(st_mode) | 是否是一个字符设备 |
S_ISBLK(st_mode) | 是否是一个块设备 |
S_ISFIFO(st_mode) | 是否是一个FIFO文件 |
S_ISSOCK(st_mode) | 是否是一个SOCKET文件 |
struct stat结构体
struct stat {
mode_t st_mode; //文件对应的模式,文件,目录等,一般用于前面的几个宏中
ino_t st_ino; //inode节点号
dev_t st_dev; //设备文件的id
dev_t st_rdev; //特殊设备id
nlink_t st_nlink; //文件的连接数
uid_t st_uid; //文件所有者
gid_t st_gid; //文件所有者对应的组
off_t st_size; //文件大小
time_t st_atime; //文件最后被访问的时间
time_t st_mtime; //文件内容最后被修改的时间
time_t st_ctime; //文件状态改变时间
blksize_t st_blksize; //文件内容对应的块大小
blkcnt_t st_blocks; //文件所占的块数
};