二话不说直接上代码(这是我之前在网易博客上写的搬过来)
ls.c 如下:
#include "ls.h"
/**********************************************************************/
//将路径定位到argv[1]目录下 打开该目录 返回指针指向该文件
//读取文件 每读取一次文件目录下的指针方向后移 并返回文件属性结构体
//由于读取文件时的文件属性结构体不完整
//所以将文件指针指向的文件名传入stat函数得到该文件名的详细属性
//获取时间时 注意范围 具体规则将man手册 man localtime
//注意类型的对应关系
/**********************************************************************/
void ls_al(char path[]){
//将目录切换到输入的文件夹下argv[1]
if(-1 == chdir(path)){
ERR_PRINT("<ls.h>In ls_al:chdir");
}
/*打开用户输入的文件夹argv[1]*/
//DIR *opendir(const char *name);
//输入文件夹路径名
//返回一个指向该文件夹指针
DIR *dir = opendir(path);//DIR* 类似 FILE*
/*读取当前文件夹下的信息*/
//struct dirent *readdir(DIR *dirp);
//输入一个文件夹指针
//返回一个该文件夹下的信息结构体
struct dirent *dir_info = readdir(dir); // It returns NULL on reaching the end of the directory
struct stat info_buf; //目录下所有文件详细信息结构体
char file_style = '-'; //文件类型
char power[10] = "---------"; //各用户对文件权限
int dev_main,dev_sub; //设备驱动号
int file_size; //文件大小
struct tm *time_struct; //时间结构体 localtime(info_buf.st_atime);
while(NULL != dir_info){ // It returns NULL on reaching the end of the directory
/*获取某个文件的详细信息存入结构体info_buf*/
//int stat(const char *path, struct stat *buf);
//输入目录下的某个文件名 要存入的结构体
if(-1 == stat(dir_info->d_name,&info_buf))
ERR_PRINT("<ls.h>In ls_al:stat");
time_struct = localtime(&info_buf.st_atime);//根据最后一次访问的时间(秒数)获取本地世纪结构体
/*获取文件的类型*/
switch(info_buf.st_mode & S_IFMT){
case S_IFSOCK:file_style = 's';break;
case S_IFLNK :file_style = 'l';break;
case S_IFREG :file_style = '-';break;
case S_IFBLK :file_style = 'b';break;
case S_IFDIR :file_style = 'd';break;
case S_IFCHR :file_style = 'c';break;
case S_IFIFO :file_style = 'p';break;
}
/*获取USR GRP OTH 的权限*/
power[0] = ((info_buf.st_mode & S_IRWXU) & S_IRUSR) ? 'r' : '-';
power[1] = ((info_buf.st_mode & S_IRWXU) & S_IWUSR) ? 'w' : '-';
power[2] = ((info_buf.st_mode & S_IRWXU) & S_IXUSR) ? 'x' : '-';
power[3] = ((info_buf.st_mode & S_IRWXG) & S_IRGRP) ? 'r' : '-';
power[4] = ((info_buf.st_mode & S_IRWXG) & S_IWGRP) ? 'w' : '-';
power[5] = ((info_buf.st_mode & S_IRWXG) & S_IXGRP) ? 'x' : '-';
power[6] = ((info_buf.st_mode & S_IRWXO) & S_IROTH) ? 'r' : '-';
power[7] = ((info_buf.st_mode & S_IRWXO) & S_IWOTH) ? 'w' : '-';
power[8] = ((info_buf.st_mode & S_IRWXO) & S_IXOTH) ? 'x' : '-';
/*获取目录下某个文件的UID GID*/
//struct passwd *getpwuid(uid_t uid);
//struct group *getgrgid(gid_t gid);
//输入某个文件的ID 由结构体info_buf.st_uid,info_buf.st_gid获得
//返回一个结构体 里面包含ID名
struct passwd *uid_struct = getpwuid(info_buf.st_uid);
struct group *gid_struct = getgrgid(info_buf.st_gid);
/*获取非设备驱动文件大小 和 设备驱动的主驱动号和副驱动号 dev_main & dev_sub*/
if('b' == file_style || 'c' == file_style){//(设备文件)
dev_main = (info_buf.st_rdev>>8)&0XFF;
dev_sub = (info_buf.st_rdev>>0)&0XFF;
//打印某一个文件的详细信息(设备文件)
printf("%c%s %3d %8s %8s %3d,%3d %4d-%d-%d %2d:%2d:%2d %s \n"
,file_style //文件类型
,power //用户对文件的权限
,info_buf.st_nlink //文件链接号
,uid_struct->pw_name //UID name
,gid_struct->gr_name //GID name
,dev_main //主驱动号
,dev_sub //副驱动号
,time_struct->tm_year+1900//年月日时分秒
,time_struct->tm_mon+1
,time_struct->tm_mday
,time_struct->tm_hour
,time_struct->tm_min
,time_struct->tm_sec
,dir_info->d_name //文件名
);
}
else{//(非设备文件)
file_size = info_buf.st_size;
//打印某一个文件的详细信息(非设备文件)
printf("%c%s %3d %8s %8s %7d %4d-%d-%d %2d:%2d:%2d %s \n"
,file_style //文件类型
,power //用户对文件的权限
,info_buf.st_nlink //文件链接号
,uid_struct->pw_name //UID name
,gid_struct->gr_name //GID name
,file_size //文件大小
,time_struct->tm_year+1900//年月日时分秒
,time_struct->tm_mon+1
,time_struct->tm_mday
,time_struct->tm_hour
,time_struct->tm_min
,time_struct->tm_sec
,dir_info->d_name //文件名
);
}
//文件指针下移一位 读取下一个文件(每读取一次 dir指针下移一位 类似指针)
dir_info = readdir(dir);
}
}
main.c
如下:
#include "alldef.h"
#include "ls.h"
/*
* 功能:C语言实现 ls -al 命令
* 作者:KayChan
* 日期:2015-08-05
*/
int main(int argc,char *argv[]){
ls_al(argv[1]);
return 0;
}
执行: ./ls + pathname