系统调用实现Linux命令 ls -al

二话不说直接上代码(这是我之前在网易博客上写的搬过来)


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 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值