MIB 6.1810实验Xv6 and Unix utilities(5)find

2023-11-21 14:30

本文主要是介绍MIB 6.1810实验Xv6 and Unix utilities(5)find,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

难度:moderate

Write a simple version of the UNIX find program for xv6: find all the files in a directory tree with a specific name. Your solution should be in the file user/find.c.

题目要求:实现find ,即在某个路径中,找出某个文件

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/fs.h"
#include "kernel/fcntl.h"char* fmt_name(char *path){static char buf[DIRSIZ+1];char *p;//find first character after last slashfor(p=path+strlen(path);p>=path&&*p!='/';p--);p++;memmove(buf,p,strlen(p)+1);return buf;
}void eq_print(char *fileName,char *findName){if(strcmp(fmt_name(fileName),findName)==0){printf("%s\n",fileName);}
}
void find(char *path,char *findName){char buf[512], *p;int fd;struct dirent de;struct stat st;if((fd = open(path, O_RDONLY)) < 0){fprintf(2, "ls: cannot open %s\n", path);return;}if(fstat(fd, &st) < 0){fprintf(2, "ls: cannot stat %s\n", path);close(fd);return;}/*int fd;声明一个文件描述符变量 fd,用于在程序中表示打开的文件或目录。struct dirent de;定义了一个结构体 dirent 变量 de,通常用于存储读取目录时的目录项信息。struct stat st;:定义了一个结构体 stat 变量 st,用于存储文件或目录的状态信息。if((fd = open(path, O_RDONLY)) < 0){ ... }:尝试以只读模式打开指定路径的文件或目录。如果 open() 函数返回的文件描述符小于 0(表示打开失败),则输出错误信息,并返回。if(fstat(fd, &st) < 0){ ... }:如果文件或目录成功打开,则使用 fstat() 函数获取文件描述符 fd 对应文件或目录的状态信息,并将结果存储在 st 结构体中。如果获取状态信息失败(fstat() 返回值小于 0),则输出错误信息,并关闭文件描述符后返回。  */switch(st.type){case T_DEVICE:case T_FILE:eq_print(path,findName);break;case T_DIR:if(strlen(path) + 1 + DIRSIZ + 1 > sizeof buf){printf("find: path too long\n");break;}strcpy(buf, path);p = buf+strlen(buf);*p++ = '/';while(read(fd, &de, sizeof(de)) == sizeof(de)){if(de.inum ==0||de.inum==1||strcmp(de.name,".")==0 || strcmp(de.name,"..")==0)continue;memmove(p, de.name, strlen(de.name));p[strlen(de.name)] = 0;find(buf,findName);}break;
/*循环:遍历目录项 read(fd, &de, sizeof(de)):使用read函数从文件描述符 fd中读取一个目录项的内容,并将读取的内容存储在 de 变量中。只要 read 函数成功读取一个目录项的大小(sizeof(de)),就会继续执行循环。循环内部:首先,通过检查 de.inum(目录项的inode号码)是否等于0或1,以及检查目录项的名称是否是.或..,来过滤掉特殊的目录项。.(点)表示当前目录,..(点点)表示父目录,它们在此处被跳过,不做进一步处理。如果目录项既不是特殊目录项.(点)或 ..(点点),也不是 inode 号码为 0 或 1,则会执行以下操作:memmove(p, de.name, strlen(de.name));:将目录项的文件名 de.name 复制到一个指定的缓冲区 buf 中,从指针 p 指向的位置开始存储。这里使用 memmove 函数是为了确保将文件名正确复制到指定的位置。p[strlen(de.name)] = 0;:在复制文件名后,将字符串末尾添加一个空字符 \0,以确保字符串以空字符结尾,形成一个 C 风格的字符串。最后,调用 find(buf, findName);,以递归方式在当前路径下的子目录中继续查找名为 findName 的文件或目录。在当前目录下的每个子目录中进行深度优先的查找操作。
*/}close(fd); 
}
/*
void find(char *path, char *findName):递归函数,接收两个参数,path 表示要搜索的路径,findName 表示要查找的文件或目录名。
代码开始通过 open() 函数尝试打开指定的路径,如果失败则会输出错误信息并返回。
使用 fstat() 函数获取文件的状态信息,如果失败也会输出相应的错误信息并关闭文件描述符后返回。
接下来 定义了一个缓冲区buf和指针p,用于构建要查找的文件或目录的完整路径。
使用 switch 语句检查文件类型:
T_FILE:表示当前路径是一个文件,则调用 eq_print() 函数
T_DIR:表示当前路径是一个目录,则进行目录的遍历和递归查找。首先检查路径长度是否过长,如果是,则输出相应错误信息。然后将当前路径复制到 buf 中,并在其末尾添加 /。接着使用 read() 函数读取目录项,并在循环中遍历目录下的所有文件和子目录。在目录遍历的循环中,会检查每个目录项的 inum 值是否为0或1(通常表示未使用的或损坏的inode),以及是否是.或..目录(表示当前目录和父目录).如果是则跳过不处理。
将当前目录项的名字添加到 buf 中,并递归调用 find() 函数,以此在当前目录中查找与 findName 匹配的文件或目录。
最后关闭打开的文件描述符 fd。
*/int main(int argc, char *argv[])
{if(argc>3){printf("find: find <path> <fileName>\n");exit(0);}find(argv[1],argv[2]);exit(0);
}

fmtname函数示意图 

find函数示意图:

 

实验结果:

这篇关于MIB 6.1810实验Xv6 and Unix utilities(5)find的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/402904

相关文章

STM32(十一):ADC数模转换器实验

AD单通道: 1.RCC开启GPIO和ADC时钟。配置ADCCLK分频器。 2.配置GPIO,把GPIO配置成模拟输入的模式。 3.配置多路开关,把左面通道接入到右面规则组列表里。 4.配置ADC转换器, 包括AD转换器和AD数据寄存器。单次转换,连续转换;扫描、非扫描;有几个通道,触发源是什么,数据对齐是左对齐还是右对齐。 5.ADC_CMD 开启ADC。 void RCC_AD

HNU-2023电路与电子学-实验3

写在前面: 一、实验目的 1.了解简易模型机的内部结构和工作原理。 2.分析模型机的功能,设计 8 重 3-1 多路复用器。 3.分析模型机的功能,设计 8 重 2-1 多路复用器。 4.分析模型机的工作原理,设计模型机控制信号产生逻辑。 二、实验内容 1.用 VERILOG 语言设计模型机的 8 重 3-1 多路复用器; 2.用 VERILOG 语言设计模型机的 8 重 2-1 多

列举你能想到的UNIX信号,并说明信号用途

信号是一种软中断,是一种处理异步事件的方法。一般来说,操作系统都支持许多信号。尤其是UNIX,比较重要应用程序一般都会处理信号。 UNIX定义了许多信号,比如SIGINT表示中断字符信号,也就是Ctrl+C的信号,SIGBUS表示硬件故障的信号;SIGCHLD表示子进程状态改变信号;SIGKILL表示终止程序运行的信号,等等。信号量编程是UNIX下非常重要的一种技术。 Unix信号量也可以

MongoDB学习—(6)MongoDB的find查询比较符

首先,先通过以下函数向BookList集合中插入10000条数据 function insertN(obj,n){var i=0;while(i<n){obj.insert({id:i,name:"bookNumber"+i,publishTime:i+2000})i++;}}var BookList=db.getCollection("BookList")调用函数,这样,BookList

61.以太网数据回环实验(4)以太网数据收发器发送模块

(1)状态转移图: (2)IP数据包格式: (3)UDP数据包格式: (4)以太网发送模块代码: module udp_tx(input wire gmii_txc ,input wire reset_n ,input wire tx_start_en , //以太网开始发送信

LTspice模拟CCM和DCM模式的BUCK电路实验及参数计算

关于BUCK电路的原理可以参考硬件工程师炼成之路写的《 手撕Buck!Buck公式推导过程》.实验内容是将12V~5V的Buck电路仿真,要求纹波电压小于15mv. CCM和DCM的区别: CCM:在一个开关周期内,电感电流从不会到0. DCM:在开关周期内,电感电流总会到0. CCM模式Buck电路仿真: 在用LTspice模拟CCM电路时,MOS管驱动信号频率为100Khz,负载为10R(可自

【NodeJS】Error: Cannot find module 'ms'

转载自:http://blog.csdn.net/echo_ae/article/details/75097004 问题: Error: Cannot find module 'ms'at Function.Module._resolveFilename (module.js:469:15)at Function.Module._load (module.js:417:25)at Module

HCIA--实验十:路由的递归特性

递归路由的理解 一、实验内容 1.需求/要求: 使用4台路由器,在AR1和AR4上分别配置一个LOOPBACK接口,根据路由的递归特性,写一系列的静态路由实现让1.1.1.1和4.4.4.4的双向通信。 二、实验过程 1.拓扑图: 2.步骤: (下列命令行可以直接复制在ensp) 1.如拓扑图所示,配置各路由器的基本信息: 各接口的ip地址及子网掩码,给AR1和AR4分别配置

leetCode#448. Find All Numbers Disappeared in an Array

Description Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once. Find all the elements of [1, n] inclusive that do not appear in this

访问controller404:The origin server did not find a current representation for the target resource

ider build->rebuild project。Rebuild:对选定的目标(Project),进行强制性编译,不管目标是否是被修改过。由于 Rebuild 的目标只有 Project,所以 Rebuild 每次花的时间会比较长。 参考:资料