操作系统第4次实验报告:文件系统
- 姓名:祁翌炀
- 学号:201821121019
- 班级:计算1811
1. 编写程序
在服务器上用Vim编写一个程序:实现Linux系统命令ls -lai
的功能,给出源代码。
2. 分析运行结果
给出运行结果截图,对于每一列是如何获取的,结合源代码做解释
suqiankun@jmu-cs-ubuntu:~$ ls -lai
total 160
920635 drwx------ 6 suqiankun ubuntu 4096 Apr 27 09:52 .
131195 drwxr-xr-x 129 root root 4096 Apr 25 21:52 ..
920658 -rw------- 1 suqiankun ubuntu 10359 Apr 27 10:38 .bash_history
920636 -rw-r--r-- 1 suqiankun ubuntu 220 Apr 5 2018 .bash_logout
920638 -rw-r--r-- 1 suqiankun ubuntu 3771 Apr 5 2018 .bashrc
920656 drwx------ 2 suqiankun ubuntu 4096 Mar 11 16:01 .cache
#include<stdio.h> #include<malloc.h> #include<string.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #include<stdlib.h> #include<dirent.h> #include<grp.h> #include<pwd.h> #include <time.h> struct file { struct file *next; char name[50]; }; //创建结构体文件链表 void print(struct file *head) //打印 { struct file *test = head; struct passwd *pwsd; struct group *gp; char kd_file[7] = {'p' , 'c' , 'd' , 'b' , '-' , 'l' , 's'}; //文件类型 char *kd_quanxian[8] = {"---" , "--x" , "-w-" , "-wx" , "r--" , "r-x" , "rw-" , "rwx"}; //权限类型 while(test != NULL) { struct stat mystat; if(stat(test->name,&mystat) == -1) { perror("stat"); exit(EXIT_FAILURE); } printf("%d ",mystat.st_mode); int index=((mystat.st_mode >> 12) & 0xF) / 2; //查询文件类型 printf("%c",kd_file[index]); printf("%s",kd_quanxian[mystat.st_mode >> 6 & 07]); //查看本人、他人、服务器权限 printf("%s",kd_quanxian[mystat.st_mode >> 3 & 07]); printf("%s ",kd_quanxian[mystat.st_mode >> 0 & 07]); printf("%ld ",mystat.st_nlink); //硬连接个数 pwsd=getpwuid(mystat.st_uid); //通过uid获取passwd数据 printf("%s ",pwsd->pw_name); gp=getgrgid(mystat.st_gid); //通过gid获取组信息 printf("%s ",gp->gr_name); printf("%ld ",mystat.st_size); //文件大小 char change[20]; memset(change,'\0',20) ; ctime_r(&mystat.st_mtime,change); //修改的时间 change[11] ='\0'; printf("%s ", change); printf(" %s\n",test->name); //文件路径 test = test->next ; } } struct file* insert_list(struct file *test , struct file *linklist) //添加路径 { if(linklist == NULL) { linklist = test ; } else { struct file *test2 ; test2 = linklist ; while(test2->next != NULL) { test2 = test2->next ; } test2->next = temp ; } return linklist ; } int main() { char path[]={"./"}; struct file *linklist = NULL; //初始化链表 struct stat mystat; DIR *mydir= NULL; struct dirent *myent = NULL; if(stat(path, &stat_info) == -1) //获取文件属性 { perror("stat"); exit(EXIT_FAILURE); } mydir = opendir(path); //打开路径 if(mydir == NULL) { perror("open dir"); exit(EXIT_FAILURE); } while(myent = readdir(mydir)) //依次读取目录下的文件 { struct file *test= (struct file *)malloc(sizeof(struct file)); if(test== NULL) { perror("malloc"); exit(EXIT_FAILURE); } test->next = NULL; memset(test->name,'\0',NAME_SIZE); //清除节点数据 memcpy(test->name,myent->d_name,strlen(myent->d_name)); //赋予新数据 linklist = insert_list(test,linklist); //加入链表 } closedir(mydir) ; print(linklist) ; //free struct fnode *test; test = linklist; while(test != NULL) { test = linklist->next; free(linklist); linklist = test; } return 0;
}
这是c实现的lai
第一列为文件索引号,代码为 st_mode
第二列首字母为文件类型,后面三个三个字依次为个人权限、组人权限、他人权限
以下为定义的人的权限类型
以下为定义的文件类型
这五行代码为 查看文件权限
第三列为硬连接个数,从
st_nlink 查看
第四列为文件对应的用户信息
第五列为文件对应用户组的信息
第六列为文件大小
文件大小用st_size
第七列为文件上次修改时间
st_mtime
第八列为文件路径
然后继续链表的下一个结点,一直到循环结束
test=null时
然后在主函数中
首先是初始化链表,依次读取文件目录,
申请空间
然后进行循环到无文件为止
把每个的数据的地址都存进linklist里面去,随后再次用链表打印
3. 通过该实验产生新的疑问及解答
这是显示单一文件的信息函数
void show_onefileinfo(char* filename, struct stat* info_p) { char* uid_to_name(), *ctime(), *gid_to_name(), *filemode(); void mode_to_letters(); char modestr[11]; mode_to_letters(info_p->st_mode, modestr); printf("%s", modestr); printf(" %4d", (int) info_p->st_nlink); printf(" %-8s", uid_to_name(info_p->st_uid)); printf(" %-8s", gid_to_name(info_p->st_gid)); printf(" %8ld", (long) info_p->st_size); printf(" %.12s", 4 + ctime(&info_p->st_mtime)); printf(" %s\n", filename); }
我认为也可以先进行
一个文件的信息输出,在通过链表查询其他的文件进行一个个输出
也就是用另一种方式把整个的文件信息给显示出来