操作系统第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. 通过该实验产生新的疑问及解答

疑问:一开始不知道第二列中第一个字母代表什么?

解答:第二列第一个字母表示的是文件的类型,接着跟着的是文件的权限。

posted @ 2020-04-30 18:05  TsoiTing  阅读(141)  评论(0编辑  收藏  举报