find
![image.png](https://i-blog.csdnimg.cn/blog_migrate/87ed26c65e372593c03db08e1e143443.png)
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/fs.h"
void find(char* path, const char* target) {
int fd;
struct dirent dt;
struct stat st;
char buf[256];
char* p;
if ((fd = open(path, 0)) < 0) {
fprintf(2, "can't open path like %s\n", path);
return;
}
if (fstat(fd, &st) < 0) {
fprintf(2, "can't stat pathfire %s\n", path);
close(fd);
return;
}
if (st.type != T_DIR) {
fprintf(2, "it's not a DIR: %s", path);
close(fd);
return;
}
if (strlen(path) + 1 + DIRSIZ + 1 > sizeof buf) {
printf("find: path too long\n");
}
strcpy(buf, path);
p = buf + strlen(buf);
*p++ = '/';
while(read(fd, &dt, sizeof(dt)) == sizeof(dt)) {
if (dt.inum == 0) continue;
memmove(p, dt.name, DIRSIZ);
p[DIRSIZ] = 0;
if (stat(buf, &st) < 0) {
printf("find: cannot stat %s\n", buf);
continue;
}
if (st.type == T_DIR && strcmp(".", p) != 0 && strcmp("..", p) != 0) {
find(buf, name);
}
else if(strcmp(name, p)==0){
printf("%s\n", buf);
}
}
close(fd);
}
int main(int argc, char* argv[]) {
if (argc != 3) {
printf("pls input like find [path] [filename]\n");
exit(1);
}
find(argv[1], argv[2]);
exit(0);
}
~
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/8987f9d511deafd521ddcc7fe59ef2d7.png)
思路
- 模仿ls.c,遍历path的目录项,读到dir递归,读到file就判断是否跟name一样
不会的
- ls.c里面有几个系统调用查了资料才会,
memmove(p, dt.name, DIRSIZ)
memmove 函数将 dt.name
指向的内存区域中的 DIRSIZ个字节的数据复制到 p 指向的内存区域中。这里DIRSIZ是宏定义,表示目录项的最大长度,一般是14 - 后半段p的位置需要注意,ls.c中先把path复制到buf中,然后在buf的末尾加了个/,再把p指向/后一个位置,后面的dt.name在p处往后添,但是p一直都在dt.name的首位。所以才可以用p跟name进行比较。