操作系统第4次实验报告:文件系统
0.个人信息
- 姓名 罗廷杨
- 学号 201821121013
- 班级 计算1811
1. 编写程序
在服务器上用Vim编写一个程序:实现Linux系统命令ls -lai
的功能,源代码如下。
#include<stdio.h> #include<string.h> #include<sys/types.h> #include<dirent.h> #include<sys/stat.h> #include<grp.h> #include<pwd.h> //得到每个文件的名字 和当前目录文件总数 完成后续操作 void do_ls(char []); //得到每个文件的具体信息 void dostat(char *); //输入信息并进行字符转化和对其格式统计 void show_file_info(char *, struct stat *); //将权限转化为字符串 void mode_to_letters(int mode, char str[]); //将uid转化成对应的名字并获取对齐长度 char *uid_to_name(uid_t uid); //将gid转化成对应的名字并获取对齐长度 char *gid_to_name(gid_t gid); int main(int argc, char **argv) { if(argc==2&&!(strcmp(argv[1],"-lai"))) { if (argc == 2)//默认当前文件夹 { do_ls("."); } else if(argc>2)//指定一个或多个文件夹 { while ((--argc)>=2) { do_ls(argv[argc]); } } } return 0; } void do_ls(char dirname[]) { DIR *dir_ptr; struct dirent *direntp; if ((dir_ptr = opendir(dirname)) == NULL) { fprintf(stderr, "ls2: cannot open %s\n", dirname); } else { //一直查找文件,知道全部查找完成 while((direntp = readdir(dir_ptr)) != NULL) { //获取查找到文件的信息,并输出 dostat(direntp->d_name); } closedir(dir_ptr); } } //得到文件的具体信息 void dostat(char *filename) { struct stat info; if (stat(filename, &info) == -1) { perror(filename); } else { show_file_info(filename, &info); } } void show_file_info(char *filename, struct stat *info_p) { char *uid_to_name(), *ctime(), *gid_to_name(); void mode_to_letters(); char modestr[11]; //获取文件信息 mode_to_letters(info_p->st_mode, modestr); //将信息输出 printf("%d ",(int)info_p->st_ino); //索引号 printf("%s",modestr); //文件类型 printf("%4d ",(int)info_p->st_nlink); //链接数 printf("%-8s ", uid_to_name(info_p->st_uid)); //用户id printf("%-8s ", gid_to_name(info_p->st_gid)); //组id printf("%8ld ", (long)info_p->st_size); //文件大小 printf("%.12s ", 4 + ctime(&info_p->st_mtime)); //修改时间 printf("%s\n", filename); //文件名 } void mode_to_letters(int mode, char str[]) { strcpy(str, "-----------"); if (S_ISDIR(mode)) str[0] = 'd';//目录文件 if (S_ISCHR(mode)) str[0] = 'c';//字符设备文件 if (S_ISBLK(mode)) str[0] = 'b';//块设备文件 if (mode & S_IRUSR) str[1] = 'r';//判断user有无读权限 if (mode & S_IWUSR) str[2] = 'w';//判断user有无写权限 if (mode & S_IXUSR) str[3] = 'x';//判断user有无可执行权限 if (mode & S_IRGRP) str[4] = 'r';//判断group有无读权限 if (mode & S_IWGRP) str[5] = 'w';//判断group有无写权限 if (mode & S_IXGRP) str[6] = 'x';//判断group有无可执行权限 if (mode & S_IROTH) str[7] = 'r';//判断other有无读权限 if (mode & S_IWOTH) str[8] = 'w';//判断other有无写权限 if (mode & S_IXOTH) str[9] = 'x';//判断other有无可执行权限 } char *uid_to_name(uid_t uid) { struct passwd * getpwuid(), *pw_ptr; static char numstr[10]; if ((pw_ptr = getpwuid(uid)) == NULL) { sprintf(numstr, "%d", uid); return numstr; } else { return pw_ptr->pw_name; } } char *gid_to_name(gid_t gid) { struct group *getgrgid(), *grp_ptr; static char numstr[10]; if ((grp_ptr = getgrgid(gid)) == NULL) { sprintf(numstr, "%d", gid); return numstr; } else { return grp_ptr->gr_name; } }
2. 分析运行结果
1.运行ls -lai命令
2.运行实现的ls -lai命令
3.代码解释
运行ls -lai命令后要求显示文件的索引号、文件类型、链接数、用户id、组id、文件大小、修改时间、文件名等信息。程序运行的时候先对指令格式进行判断,如果是ls -lai 文件路径(文件路径可省略,省略就为当前路径)这种形式,那么就调用void do_ls(char dirname[]);这个函数来执行 opendir(dirname)来进入路径,如果能正常进入到相应的文件路径下,那么就再调用void dostat(char *);这个函数来得到相应的文件,然后利用void show_file_info(char *filename, struct stat *info_p);函数来调用char *uid_to_name(uid_t uid);函数、char *gid_to_name(gid_t gid);函数、void mode_to_letters(int mode, char str[]);函数等三个函数来获得该文件的索引号、文件类型、链接数、用户id、组id、文件大小、修改时间、文件名等具体信息,然后分别将这些信息输出。
3. 通过该实验产生新的疑问及解答
如何实现对不同格式的文件名标上不同的颜色?
需要先设定好不同的颜色属性,然后在输出的时候分别对每个文件的格式进行判断,为它们分配上预先设定的颜色属性,这样一来就可以在控制台中看见不同类型的文件用不同的颜色标识出来。