必做作业:mystat实现

作业要求

学习使用stat(1),并用C语言实现

  1. 提交学习stat(1)的截图
  2. man -k ,grep -r的使用
  3. 伪代码
  4. 产品代码 mystate.c,提交码云链接
  5. 测试代码,mystat 与stat(1)对比,提交截图

完成过程

1. 学习stat(1)的截图

使用man 1 stat进行学习。通过学习知道了stat的作用,用法,参数等。stat主要是用于查询一个文件或路径的信息。

测试使用stat:

2. man -k ,grep -r的使用

man -k的使用

要实现stat,我想到是否可以使用系统调用或者现有C函数进行编程,所以使用man -k进行查找搜索。
使用man -k stat | grep file查找与stat(状态)和file(文件)相关的内容,找到了如下内容。

非常多的内容,其中,我进一步了解名为stat的系统调用。

man 2 stat查看学习。

发现通过使用stat系统调用,会返回一个结构体,其中包含了我们需要输出的信息。按理说只要根据文件路径获取到这个结构体,然后再进行格式化输出就可以了。

grep -r的使用

在实现的过程中,会遇到很多不知道的类型和宏定义,需要使用grep -r xx /usr/include
如:第二个需要输出的,是文件大小。

发现有一个变量:st_size不清楚其类型意义。使用grep -r st_size /usr/include查询。

3. 伪代码

//使用命令行传入文件路径参数argv
main{
  struct stat st;//首先定义stat结构体
  stat(argv,st);//根据文件路径,将文件信息写入结构体

  printf(st.xx);//根据stat的输出,将相应的信息进行输出就可以啦
  //(格式化输出时,对于文件的类型,需要单独进行判定,可以使用switch语句实现)
}
  1. 产品代码
    在编写时,发现stat中没有文件权限,还需要从
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int rwxMode[] = {0,S_IRUSR, S_IWUSR, S_IXUSR, S_IRGRP, S_IWGRP, S_IXGRP, S_IROTH, S_IWOTH, S_IXOTH};

char getFileType(mode_t mode){
  if(S_ISDIR(mode)) return 'd';
  else if(S_ISCHR(mode))  return 'c';
  else if(S_ISBLK(mode)) return 'b';
  else if(S_ISFIFO(mode)) return 'f';
  else if(S_ISLNK(mode)) return 'l';
  else if(S_ISSOCK(mode)) return 's';
  else return '-';
}

int main(int argc, char *argv[])
{
    struct stat st;
    if (argc != 2)
    {
        fprintf(stderr, "使用“stat <filename or dirname>”。\n");
        exit(EXIT_FAILURE);
    }
    if (stat(argv[1], &st) == -1)
    {
        perror("stat");
        exit(EXIT_FAILURE);
    }
    printf("  文件: %s\n", argv[1]);
    printf("  大小:%ld\t\t",(long)st.st_size);
    printf("  块: %lld\t\t", (long long)st.st_blocks);
    printf("IO 块: %ld  ", (long)st.st_blksize);
    switch (st.st_mode & S_IFMT)
    {
    case S_IFBLK:
        printf("块设备\n");
        break;
    case S_IFCHR:
        printf("character device\n");
        break;
    case S_IFDIR:
        printf("目录\n");
        break;
    case S_IFIFO:
        printf("FIFO/管道\n");
        break;
    case S_IFLNK:
        printf("符号链接\n");
        break;
    case S_IFREG:
        printf("普通文件\n");
        break;
    case S_IFSOCK:
        printf("socket\n");
        break;
    default:
        printf("未知?\n");
        break;
    }
    printf("设备: %lxh/%lud\t",st.st_dev,st.st_dev);
    printf("Inode: %ld\t\t", (long)st.st_ino);
    printf("硬连接: %ld\n", (long)st.st_nlink);
    char fileMode[11];
    strcpy(fileMode, "-rwxrwxrwx");
    fileMode[0] = getFileType(st.st_mode);
    for(int j = 1; j < 10; ++j)
      if(!(st.st_mode & rwxMode[j])) fileMode[j] = '-';
    printf("权限: (%s)",fileMode);
    printf("\tidD=( %ld/   lzh)   Gid=( %ld/   lzh)\n", (long)st.st_uid, (long)st.st_gid);
    printf("最近访问: %s", ctime(&st.st_atime));
    printf("最近更改: %s", ctime(&st.st_mtime));
    printf("最近改动: %s", ctime(&st.st_ctime));
    printf("创建时间: -\n");
    exit(EXIT_SUCCESS);
}

码云链接:https://gitee.com/Ressurection20191320/code/blob/master/IS/mystat/mystat.c

5. 对照

posted @ 2021-11-04 22:00  20191320  阅读(77)  评论(0编辑  收藏  举报