zoukankan      html  css  js  c++  java
  • 操作系统第4次实验报告:文件系统

    • 姓名:吕煜华
    • 学号:201821121046
    • 班级:计算1812

    1. 编写程序

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

      1 #include<stdio.h>
      2 #include<stdlib.h>
      3 #include<string.h>
      4 #include<unistd.h>
      5 #include<dirent.h>
      6 #include<sys/stat.h>
      7 #include<sys/types.h>
      8 #include<time.h>
      9 #include<fcntl.h>
     10 #include<pwd.h>
     11 #include<grp.h>
     12
     13 void error_printf(const char*);
     14 void list_dir(const char*);
     15 void list_message(const char*, const struct stat*);
     16 void file_type(const struct stat*);
     17 void file_power(const struct stat*);
     18 void file_id(const struct stat*);
     19 void file_mtime(const struct stat*);
     20 void link_printf(const char*);
     21
     22 void error_printf(const char* funname){
     23     perror(funname);
     24     exit(1);
     25 }
     26
     27 void list_dir(const char* pathname){
     28     DIR* ret_opendir = opendir(pathname); //打开目录
     29     if(ret_opendir == NULL)
     30         error_printf("opendir");
     31
     32     int ret_chdir = chdir(pathname);  //转到”pathname“,便于stat函数的使用
     33     if(ret_chdir == -1)
     34         error_printf("chdir");
     35
     36     struct dirent* ret_readdir =NULL;
     37     while(ret_readdir = readdir(ret_opendir))
     38     {
     39         char* filename = ret_readdir->d_name;  //获取文件名
     40         struct stat file_message ={};
     41         int ret_stat = lstat(filename, &file_message); //获取文件信息
     42         if(ret_stat == -1)
     43             printf("%s error!", filename);
     44         else if(strcmp(filename,".") && strcmp(filename, ".."))
     45             list_message(filename, &file_message);
     46     }
     47 }
     48
     49 void list_message(const char* filename, const struct stat* file_message){
     50     file_type(file_message); // 判断打印类型
     51
     52     printf("%d ",(int)file_message->st_ino); //添加索引号
     53     file_power(file_message); //判断并打印文件权限
     54     printf("%3ld ",file_message->st_nlink); //打印硬链接数
     55     file_id(file_message); //转换并打印用户id与组id
     56     printf("%5ld ", file_message->st_size);  //打印文件大小
     57     file_mtime(file_message);  //打印文件最后修改时间
     58     printf("%s ", filename);  //打印文件名
     59     if(S_ISLNK(file_message->st_mode))  //如果是软链接文件打印其指向的位置
     60         link_printf(filename);
     61     puts("");
     62 }
     63
     64 void file_type(const struct stat* file_message){
     65     mode_t mode = file_message->st_mode;
     66
     67     if(S_ISREG(mode))        printf("-"); //普通文件
     68     else if(S_ISDIR(mode))   printf("d"); //目录文件
     69     else if(S_ISCHR(mode))   printf("c"); //字符设备文件
     70     else if(S_ISBLK(mode))   printf("b"); //块设备文件
     71     else if(S_ISFIFO(mode))  printf("p"); //管道文件
     72     else if(S_ISLNK(mode))   printf("l"); //链接文件
     73     else                     printf("s"); //socket文件
     74 }
     75
     76 void file_power(const struct stat* file_message){
     77     mode_t mode = file_message->st_mode;
     78
     79     printf("%c", mode&S_IRUSR?'r':'-');
     80     printf("%c", mode&S_IWUSR?'w':'-');
     81     printf("%c", mode&S_IXUSR?'x':'-');
     82
     83     printf("%c", mode&S_IRGRP?'r':'-');
     84     printf("%c", mode&S_IWGRP?'w':'-');
      85     printf("%c", mode&S_IXGRP?'x':'-');
     86
     87     printf("%c", mode&S_IROTH?'r':'-');
     88     printf("%C", mode&S_IWOTH?'w':'-');
     89     printf("%c ", mode&S_IXOTH?'x':'-');
     90 }
     91
     92 void file_id(const struct stat* file_message){
     93     struct passwd* pwd;
     94     pwd = getpwuid(file_message->st_uid);
     95     printf("%s ", pwd->pw_name);
     96
     97     struct group* grp;
     98     grp = getgrgid(file_message->st_gid);
     99     printf("%s ", grp->gr_name);
    100 }
    101
    102 void file_mtime(const struct stat* file_message){
    103     struct tm* t = localtime(&file_message->st_mtime);
    104     printf("%2d月%2d日 %2d:%2d ", t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm    _min);
     105 }
    106
    107 void link_printf(const char* filename){
    108     char buf[1024] = "123";
    109     if(0 == readlink(filename, buf, sizeof(buf)))
    110         error_printf("readlink");
    111     printf("-> %s ", buf);
    112 }
    113
    114 int main()
    115 {
    116     char path[1024] = {};
    117     strcpy(path, "./");
    118     struct stat file_message={};
    119
    120     int ret_stat = lstat(path, &file_message);
    121     if(ret_stat == -1)
    122         error_printf("stat");
    123
    124     if(S_ISDIR(file_message.st_mode))  //判断是否为目录
    125         list_dir(path);
    126     else
    127         list_message(path, &file_message);
    128     return 0;
    129 }
    130
                                                   

    2. 分析运行结果

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

    分析结果如下:

    (1)第一列为文件索引号

    printf("%d ",(int)file_message->st_ino);//添加索引号

    (2)第二列首字母为文件类型,后面的 “r” 、“w”、“x”为读、写、执行的权限。

    void file_type(const struct stat* file_message)
    {
        mode_t mode = file_message->st_mode;
     
        if     (S_ISREG(mode))  printf("-"); // 普通文件
        else if(S_ISDIR(mode))  printf("d"); // 目录文件
        else if(S_ISCHR(mode))  printf("c"); // 字符设备文件
        else if(S_ISBLK(mode))  printf("b"); // 块设备文件
        else if(S_ISFIFO(mode)) printf("p"); // 管道文件
        else if(S_ISLNK(mode))  printf("l"); // 链接文件
        else                    printf("s"); // socket文件
    }
    void file_power(const struct stat* file_message)
    {
        mode_t mode = file_message->st_mode;
     
     
        printf("%c", mode&S_IRUSR?'r':'-');
        printf("%c", mode&S_IWUSR?'w':'-');
        printf("%c", mode&S_IXUSR?'x':'-');
     
     
        printf("%c", mode&S_IRGRP?'r':'-');
        printf("%c", mode&S_IWGRP?'w':'-');
        printf("%c", mode&S_IXGRP?'x':'-');
     
        printf("%c", mode&S_IROTH?'r':'-');
        printf("%c", mode&S_IWOTH?'w':'-');
        printf("%c ", mode&S_IXOTH?'x':'-');
    }

    (3)第三列为文件硬链接个数

    printf("%3ld ", file_message->st_nlink); // 打印硬链接数

    (4)第四列为文件用户信息

      struct passwd* pwd;
        pwd = getpwuid(file_message->st_uid);
        printf("%s ",pwd->pw_name);

    (5)第五列为文件用户组信息

      struct group* grp;
        grp = getgrgid(file_message->st_gid);
        printf("%s ",grp->gr_name);

    (6)第六列为文件大小

    printf("%5ld ", file_message->st_size); // 打印文件大小

    (7)第七列为文件上次修改的时间

    void file_mtime(const struct stat* file_message)
    {
        struct tm* t = localtime(&file_message->st_mtime);
        printf("%2d月%2d日 %02d:%02d ", t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min); // 打印文件上次修改的时间
    }

    (8)第八列为文件名

    printf("%s ", filename); // 打印文件名

    3. 通过该实验产生新的疑问及解答

    了解了ls -lai

    ls -l   #以长格式显示目录下的内容列表。输出的信息从左到右依次包括文件名,文件类型、权限模式、硬连接数、所有者、组、文件大小和文件的最后修改时间等
    ls -a   #显示所有档案及目录(ls内定将档案名或目录名称为“.”的视为隐藏,不会列出)
    ls -i   #显示文件索引节点号(inode number),一个索引节点代表一个文件
  • 相关阅读:
    增强遍历和Object多参数遍历
    Git忽略规则(.gitignore配置)不生效原因和解决
    算法基本概念及常用算法Python实现
    使用GitBook编写项目文档
    Python 闭包
    Linux 进程管理
    Kafka 安装及入门
    IP地址0.0.0.0表示什么
    Docker 入门
    Docker Linux下安装
  • 原文地址:https://www.cnblogs.com/lvyuhua/p/12811389.html
Copyright © 2011-2022 走看看