首先我们对Linux下ls命令已经非常熟悉了,我在这里用C语言仅实现ls -l及ls -l xxx。(仅作练习使用)
首先需要了解ls -l命令都做了那些活动,那么就需要研究以下:
我们可以看到有七列主要内容,先来逐个分析:
- 文件的类型,此图里所有文件均为目录,所以是d。权限=本用户权限+本组用户权限+其他用户权限
- 硬链接数
- 文件所输用户名 文件所输用户组名
- 文件大小
- 时间(这个时间是该文件最后一次被修改的时间)
- 文件名
为了获取以上信息,我们可以使用一个库里的函数来帮助我们。
可以看到我们所需要的信息都在该函数的结构体被定义。我们可以直接使用这些接口获取。以下附上代码:
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <stdlib.h>
#include <dirent.h>
int file_type(md)
{
//file type
char type[12]="?---------.";
if((md & S_IFMT)==S_IFREG) type[0]='-';
if((md & S_IFMT)==S_IFSOCK) type[0]='s';
if((md & S_IFMT)==S_IFLNK) type[0]='l';
if((md & S_IFMT)==S_IFDIR) type[0]='d';
if((md & S_IFMT)==S_IFCHR) type[0]='c';
if((md & S_IFMT)==S_IFIFO) type[0]='p';
if((md & S_IFMT)==S_IFBLK) type[0]='b';
if(md & S_IRUSR) type[1]='r';
if(md & S_IWUSR) type[2]='w';
if(md & S_IXUSR) type[3]='x';
if(md & S_IRGRP) type[4]='r';
if(md & S_IWGRP) type[5]='w';
if(md & S_IXGRP) type[6]='x';
if(md & S_IROTH) type[7]='r';
if(md & S_IWOTH) type[8]='w';
if(md & S_IXOTH) type[9]='x';
printf("%s ",type);
}
int file_ls(char *pd)
{
struct stat sbuf;
lstat(pd,&sbuf);
file_type(sbuf.st_mode);//type
printf("%d ",sbuf.st_nlink);//hard-link
//user name and group name
struct passwd *pu = getpwuid(sbuf.st_uid);
if(pu!=NULL)
{
printf("%s ",pu->pw_name);
}
struct group *gd=getgrgid(sbuf.st_gid);
if(gd!=NULL)
{
printf("%s ",gd->gr_name);
}
//file size
printf("%04d ",sbuf.st_size);
//file time
struct tm *tf=localtime(&sbuf.st_mtime);
printf("%04d/%02d/%02d ",(tf->tm_year+1900),(tf->tm_mon+1),tf->tm_mday);
printf("%4d:%02d:%02d ",(tf->tm_hour),(tf->tm_min),tf->tm_sec);
//file name
printf("%s",pd);
//symbolic-link
if(S_ISLNK(sbuf.st_mode))
{
printf(" -> ");
char buf[256]={};
int len=sizeof(buf);
readlink(pd,buf,len);
printf("%s ",buf);
}
printf("\n");
}
int main(int argc,char *argv[])
{
if(argc==1)
{
//all file
DIR* pdir=opendir(".");
if(pdir==NULL)
{
fprintf(stderr,"open dir error!\n");
return -1;
}
struct dirent *pd=NULL;
while((pd=readdir(pdir))!=NULL)
{
//printf("%s\n",pd->d_name);
file_ls(pd->d_name);
}
}
else if(argc==2)
{
file_ls(argv[1]);
}
}