操作系统第四次实验报告:文件系统

  • 姓名:倪晓东
  • 学号:201821121020
  • 班级:计算1811

1. 编写程序

在服务器上用Vim编写一个程序:实现Linux系统命令ls -lai的功能,给出源代码。

源代码:

#include<stdio.h>
  2 #include<sys/types.h>      //基本系统数据类型头文件,含有size_t,time_t,pid_t等类型
  3 #include<dirent.h>         //为获取某文件目录内容
  4 #include<sys/stat.h>       //系统定义文件状态所在的伪标准头文件
  5 #include<pwd.h>
  6 #include<grp.h>
  7 #include<unistd.h>
  8 #include<string.h>
  9
 10 #define LS_NONE 0           //初始化参数
 11 #define LS_L 101
 12 #define LS_I 102
 13 #define LS_A 200
 14 #define LS_AL (LS_A+LS_L)
 15 #define LS_AI (LS_A+LS_I)
 16 #define LS_LAI (LS_L+LS_A+LS_I)
 17
 18 void show_file_info(char* filename,struct stat* info_p);
 19 void mode_to_letters(int mode,char str[]);
 20 char* uid_to_name(uid_t uid);
 21 char* gid_to_name(gid_t gid);
 22 void do_ls(char dirname[],int mode);
 23 int analyzeparam(char* input);
 24
 25 int main(int ac,char* av[]){
 26     if(ac==1){
 27         do_ls(".",LS_NONE);
 28     }
 29     else{
 30         int mode=LS_NONE;
 31         int have_file_param=0;
 32         while(ac>1){
 33             ac--;
 34             av++;
 35             int calmode=analyzeparam(*av);
 36             if(calmode!=-1){
 37                 mode+=calmode;
 38             }
 39             else{
 40                 have_file_param=1;
 41                 do{
 42                         printf("%s:\n",*av);
 43                         do_ls(*av,mode);
 44                         printf("\n");
 45                         ac--;
 46                         av++;
 47                         }while(ac>=1);
 48                         }
 49                         }
 50         if(!have_file_param){
 51         do_ls(".",mode);
 52         }
 53         }
 54         }
 55
 56 void show_file_info(char* filename,struct stat* info_p){
 57     char* uid_to_name(),*ctime(),*gid_to_name(),*filemode();
 58     void mode_to_letterts();
 59     char modestr[11];
 60     mode_to_letters(info_p->st_mode,modestr);
 61     printf("%s",modestr);
 62     printf(" %4d",(int)info_p->st_nlink);
 63     printf(" %-8s",uid_to_name(info_p->st_uid));
 64     printf(" %-8s",gid_to_name(info_p->st_gid));
 65     printf(" %8ld",(long) info_p->st_size);
 66     printf(" %.12s",4+ctime(&info_p->st_mtime));
 67     printf(" %s\n",filename);
 68 }
 69 void mode_to_letters(int mode,char str[]){
 70     strcpy(str,"--------");
 71     if(S_ISDIR(mode)){
 72         str[0]='d';
 73     }
 74     if(S_ISCHR(mode)){
 75         str[0]='c';
 76     }
 77     if(S_ISBLK(mode)){
 78         str[0]='b';
 79     }
 80     if((mode &S_IRUSR)){
 81         str[1]='r';
 82     }
 83     if((mode&S_IWUSR)){
 84         str[2]='w';
 85     }
 86     if((mode&S_IXUSR)){
 87         str[3]='x';
 88     }
 89     if((mode&S_IRGRP)){
 90         str[4]='r';
 91     }
 92     if((mode&S_IWGRP)){
 93         str[5]='w';
 94     }
 95     if((mode&S_IXGRP)){
 96         str[6]='x';
 97     }
 98     if((mode&S_IROTH)){
 99         str[7]='r';
100     }
101     if((mode&S_IWOTH)){
102         str[8]='w';
103     }
104     if((mode&S_IXOTH)){
105         str[9]='x';
106     }
107 }
108 char* uid_to_name(uid_t uid){
109     struct passwd* getpwuid(),* pw_ptr;
110     static char numstr[10];
111     if((pw_ptr=getpwuid(uid))==NULL){
112         sprintf(numstr,"%d",uid);
113         return numstr;
114     }
115     else{
116         return pw_ptr->pw_name;
117     }
118 }
119 char* gid_to_name(gid_t gid){
120     struct group* getgrgid(),* grp_ptr;
121     static char numstr[10];
122     if((grp_ptr=getgrgid(gid))==NULL){
123         sprintf(numstr,"%d",gid);
124         return numstr;
125     }
126     else{
127         return grp_ptr->gr_name;
128     }
129 }
130 int analyzeparam(char* input){
131     if(strlen(input)==2){
132         if(input[1]=='l')return LS_L;
133         if(input[1]=='a')return LS_A;
134         if(input[1]=='i')return LS_I;
135     }
136     else if(strlen(input)==3){
137         if(input[1]=='a'&&input[2]=='l')return LS_AL;
138         if(input[1]=='a'&&input[2]=='i')return LS_AI;
139     }
140     else if(strlen(input)==4){
141         if(input[1]=='l'&&input[2]=='a'&&input[3]=='i')return LS_LAI;
142     }
143     return -1;
144 }
145 void do_ls(char dirname[],int mode){
146     DIR* dir_ptr;
147     struct dirent* direntp;
148     if((dir_ptr=opendir(dirname))==NULL){
149         fprintf(stderr,"ls2:cannot open %s \n",dirname);
150     }
151     else{
152         if(mode==LS_A){
153             printf("%s\n",dirname);
154         }
155         else{
156             char dirs[20][100];
157             int dir_count=0;
158             while((direntp=readdir(dir_ptr))!=NULL){
159                 if(mode<200&&direntp->d_name[0]=='.'){
160                     continue;
161                 }
162                 char complete_d_name[200];
163                 strcpy (complete_d_name,dirname);
164                 strcat (complete_d_name,"/");
165                 strcat (complete_d_name,direntp->d_name);
166                 struct stat info;
167                 if(stat(complete_d_name,&info)==-1){
168                     perror(complete_d_name);
169                 }
170                 else{
171                     if(mode==LS_L||mode==LS_AL){
172                         show_file_info(direntp->d_name,&info);
173                     }
174                     else if(mode==LS_A||mode==LS_NONE||mode==LS_I||mode==LS_AI){
175                         if(mode==LS_I||mode==LS_AI){
176                             printf("%llu ",direntp->d_ino);
177                         }
178                         printf("%s\n",direntp->d_name);
179                     }
180                     else if(mode==LS_LAI){
181                         printf("%llu ",direntp->d_ino);
182                         show_file_info(direntp->d_name,&info);
183                     }
184                 }
185             }
186         }
187         closedir(dir_ptr);
188     }
189 }

 

          

2. 分析运行结果

给出运行结果截图,对于每一列是如何获取的,结合源代码做解释

运行结果:

 使用命令ls -lai:

 

 

第1行:总计(total)

Total后面的数字是指当前目录下所有文件所占用的空间总和。在程序没有这个统计。

第1字段: 索引节点号

每行前面的数字组,一个索引节点号表示一个文件

 实现代码:

printf("%llu ", direntp->d_ino);

第2字段: 文件属性字段

 每行第二个组成部分:,由10个字母组成;第一个字符代表文件的类型。

在Linux文件属性字段中第一个字符表示文件类别,代表的含义如下:
 -:普通文件
 d:目录文件
  b:块设备文件
c:字符设备文件
 l:符号链接文件
后面9个字符代表3组访问权限:
第1组的3个字符是授权文件所有者的权限;
第2组的3个字符是授权同组用户的权限;
第3组的3个字符是授权其他用户的权限。
每一组的3个字符一次表示读、写、执行权限,其中:
r:表示有读权限
w:表示有写权限
x:表示有执行权限
-:表示没有相应的权限
 
实现代码: 
void mode_to_letters(int mode,char str[]){
 70     strcpy(str,"--------");
 71     if(S_ISDIR(mode)){
 72         str[0]='d';
 73     }
 74     if(S_ISCHR(mode)){
 75         str[0]='c';
 76     }
 77     if(S_ISBLK(mode)){
 78         str[0]='b';
 79     }
 80     if((mode &S_IRUSR)){
 81         str[1]='r';
 82     }
 83     if((mode&S_IWUSR)){
 84         str[2]='w';
 85     }
 86     if((mode&S_IXUSR)){
 87         str[3]='x';
 88     }
 89     if((mode&S_IRGRP)){
 90         str[4]='r';
 91     }
 92     if((mode&S_IWGRP)){
 93         str[5]='w';
 94     }
 95     if((mode&S_IXGRP)){
 96         str[6]='x';
 97     }
 98     if((mode&S_IROTH)){
 99         str[7]='r';
100     }
101     if((mode&S_IWOTH)){
102         str[8]='w';
103     }
104     if((mode&S_IXOTH)){
105         str[9]='x';
106     }
107 }

其中文件权限宏变量:

S_IRUSR            //用户有读权限
S_IWUSR           //用户有写权限
S_IXUSR            //用户有执行权限
S_IRGRP           //组有读权限
S_IWGRP          //组有写权限
S_IXGRP           //组有执行权限
S_IROTH           //其他人有读权限
S_IWOTH          //其他人有写权限
S_IXOTH           //其他人有可执行权限

第3字段:文件硬链接数

该字段表示文件的硬链接数,如果是一个目录,则表示该目录下子目录的个数

实现代码:printf(" %4d", (int) info_p->st_nlink);

第4字段:文件(目录)拥有者

该字段表示这个文件的拥有者

实现代码:

char* uid_to_name(uid_t uid) 

第5字段:文件(目录)拥有者所在的组

拥有者可以加入多个组,一个主组

实现代码:

char* gid_to_name(gid_t gid)  

第6字段: 文件所占用的空间(以字节为单位)

该字段表示当前文件或者文件夹大小

实现代码:

printf(" %8ld", (long) info_p->st_size);  

第7字段:文件(目录)最近访问(修改)时间

该字段表示该文件最近一次修改时间

实现代码:

printf(" %.12s", 4 + ctime(&info_p->st_mtime)); 

第8字段:文件名

实现代码:

printf(" %s\n", filename);

 

Linux ls命令:

-A列出所有条目,除了.(点)和..(点-点)

-i显示每个文件报告第一列中的索引节点数目

-l(显示方式、链接数目、所有者、组、大小(按字节)和每个文件最近一次修改时间

 3.参考资料:

https://www.cnblogs.com/fakerli/p/12105440.html

posted @ 2020-04-30 21:59  Linial  阅读(364)  评论(0编辑  收藏  举报