必做作业:mystat实现
作业要求
学习使用stat(1),并用C语言实现
- 提交学习stat(1)的截图
- man -k ,grep -r的使用
- 伪代码
- 产品代码 mystate.c,提交码云链接
- 测试代码,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语句实现)
}
- 产品代码
在编写时,发现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