操作系统第4次实验报告:文件系统
姓名:蔡婷婷 学号:201821121003 班级:计算1811
1. 编写程序
在服务器上用Vim编写一个程序:实现Linux系统命令ls -lai的功能,给出源代码。
1)执行Linux系统命令ls -lai
caitingting@jmu-cs-ubuntu:~$ ls -lai
2)参照ls -lai的功能,用vim编写程序ls-lai.c,源代码:
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <sys/types.h>
4 #include <sys/stat.h>
5 #include <dirent.h>
6 #include <unistd.h>
7 #include <string.h>
8 #include <fcntl.h>
9 #include <time.h>
10 #include <pwd.h>
11 #include <grp.h>
12
13 void file_power(const struct stat*);
14 void file_id(const struct stat*);
15 void file_mtime(const struct stat*);
16
17 void printf_error(const char* funname){
18 perror(funname);
19 exit(EXIT_FAILURE);
20 }
21 void printf_link(const char* filename){
22 char buf[1024]="123";
23 if(readlink(filename,buf,sizeof(buf))==0)
24 printf_error("readlink");
25 printf("-> %s",buf);
26 }
27 void list_message(const char* filename,const struct stat* file_message){
28 printf("%d\t",(int)file_message->st_ino); //打印索引号
29 file_power(file_message); //打印文件权限
30 printf("%ld\t",file_message->st_nlink); //打印硬链接数
31 file_id(file_message); //打印用户ID和组ID
32 printf("%5ld\t",file_message->st_size); //打印文件大小
33 file_mtime(file_message); //打印文件最后修改时间
34 printf("%s\t",filename); //打印文件名
35 if(S_ISLNK(file_message->st_mode))
36 printf_link(filename);
37 puts("");
38 }
39 void list_dir(const char* pathname){
40 DIR* ret_opendir=opendir(pathname); //打开目录
41 if(ret_opendir==NULL)
42 printf_error("opendir");
43 int ret_chdir=chdir(pathname);
44 if(ret_chdir ==-1)
45 printf_error("chdir");
46 struct dirent* ret_readdir=NULL;
47 while(ret_readdir=readdir(ret_opendir)){
48 char* filename=ret_readdir->d_name; //获取文件名
49 struct stat file_message={};
50 int ret_stat=lstat(filename,&file_message);//获取文件信息
51 if(ret_stat==-1)
52 printf("%s error",filename);
53 else if(strcmp(filename,".") && strcmp(filename,".."))
54 list_message(filename,&file_message);
55 }
56 }
57 void file_power(const struct stat* file_message){
58 mode_t mode=file_message->st_mode;
59 if (S_ISREG(mode)) printf("-");
60 else if (S_ISDIR(mode)) printf("d");
61 else if (S_ISCHR(mode)) printf("c");
62 else if (S_ISBLK(mode)) printf("b");
63 else if (S_ISFIFO(mode)) printf("p");
64 else if (S_ISLNK(mode)) printf("l");
65 else printf("s");
66 printf("%c",mode&S_IRUSR?'r':'-');
67 printf("%c",mode&S_IWUSR?'w':'-');
68 printf("%c",mode&S_IXUSR?'x':'-');
69 printf("%c",mode&S_IRGRP?'r':'-');
70 printf("%c",mode&S_IWGRP?'w':'-');
71 printf("%c",mode&S_IXGRP?'x':'-');
72 printf("%c",mode&S_IROTH?'r':'-');
73 printf("%c",mode&S_IWOTH?'w':'-');
74 printf("%c\t",mode&S_IXOTH?'x':'-');
75 }
76 void file_id(const struct stat* file_message){
77 struct passwd* pwd;
78 pwd=getpwuid(file_message->st_uid);
79 printf("%s\t",pwd->pw_name);
80 struct group* grp;
81 grp=getgrgid(file_message->st_gid);
82 printf("%s\t",grp->gr_name);
83 }
84 void file_mtime(const struct stat* file_message){
85 struct tm* t=localtime(&file_message->st_mtime);
86 printf("%2d月 %2d %02d:%02d\t",t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min);
87 }
88 int main(){
89 char path[1024]={};
90 strcpy(path,"./");
91 struct stat file_message={};
92 int ret_stat=lstat(path,&file_message);
93 if(ret_stat==-1)
94 printf_error("stat");
95 if(S_ISDIR(file_message.st_mode))
96 list_dir(path);
97 else
98 list_message(path,&file_message);
99 return 0;
100 }
2. 分析运行结果
给出运行结果截图,对于每一列是如何获取的,结合源代码做解释
1)编译运行ls-lai.c
caitingting@jmu-cs-ubuntu:~$ ./ls-lai
2)结合源代码解释
①第一列:文件或目录索引号
28 printf("%d\t",(int)file_message->st_ino); //打印索引号
②第二列:文件的类型和权限
类型:-普通文件,d目录文件,c字符设备文件,b块设备文件,p管道文件,l链接文件,socket文件
权限:r读权限,w写权限,x执行权限
(前三个表示文件拥有者的权限,中间三个表示文件所属组拥有的权限,后三个表示其他用户拥有的权限)
57 void file_power(const struct stat* file_message){
58 mode_t mode=file_message->st_mode;
59 if (S_ISREG(mode)) printf("-");
60 else if (S_ISDIR(mode)) printf("d");
61 else if (S_ISCHR(mode)) printf("c");
62 else if (S_ISBLK(mode)) printf("b");
63 else if (S_ISFIFO(mode)) printf("p");
64 else if (S_ISLNK(mode)) printf("l");
65 else printf("s");
66 printf("%c",mode&S_IRUSR?'r':'-');
67 printf("%c",mode&S_IWUSR?'w':'-');
68 printf("%c",mode&S_IXUSR?'x':'-');
69 printf("%c",mode&S_IRGRP?'r':'-');
70 printf("%c",mode&S_IWGRP?'w':'-');
71 printf("%c",mode&S_IXGRP?'x':'-');
72 printf("%c",mode&S_IROTH?'r':'-');
73 printf("%c",mode&S_IWOTH?'w':'-');
74 printf("%c\t",mode&S_IXOTH?'x':'-');
75 }
③第三列:文件硬链接数
30 printf("%ld\t",file_message->st_nlink); //打印硬链接数
④第四列和第五列:用户ID和组ID
76 void file_id(const struct stat* file_message){
77 struct passwd* pwd;
78 pwd=getpwuid(file_message->st_uid);
79 printf("%s\t",pwd->pw_name);
80 struct group* grp;
81 grp=getgrgid(file_message->st_gid);
82 printf("%s\t",grp->gr_name);
83 }
⑤第六列:文件大小
32 printf("%5ld\t",file_message->st_size); //打印文件大小
⑥第七、八、九列:文件最后修改时间
84 void file_mtime(const struct stat* file_message){
85 struct tm* t=localtime(&file_message->st_mtime);
86 printf("%2d月 %2d %02d:%02d\t",t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min);
87 }
⑦第十列:文件名
34 printf("%s\t",filename); //打印文件名
3. 通过该实验产生新的疑问及解答
疑问:一开始不知道第二列中第一个字母代表什么?
解答:第二列第一个字母表示的是文件的类型,接着跟着的是文件的权限。