操作系统第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);    
}  

我认为也可以先进行

一个文件的信息输出,在通过链表查询其他的文件进行一个个输出

也就是用另一种方式把整个的文件信息给显示出来

 

 

 

posted @ 2020-04-30 15:05  QBB  阅读(144)  评论(0编辑  收藏  举报