[!] NOTE: Gotta review it thoroughly. Didn't fully understand the code I wrote. It was a lucky shot.
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/fs.h"
void strcat(char* str1, char* str2) {
int str1Len = strlen(str1);
for (int i = 0; i < strlen(str2); i++) {
str1[str1Len + i] = str2[i];
}
str1[strlen(str1)] = 0;
}
__attribute__((noreturn)) void find(char* InitDir, char* FileName) {
int fd_dir; // fd for Directory
//int fd_spare = 0; // fd for a File
char CurDir[512] = { 0, };
struct stat st;
struct dirent de;
if ((fd_dir = open(InitDir, 0)) < 0) {
fprintf(2, "[!] failed to open %s\n", InitDir);
close(fd_dir);
exit(1);
}
if (fstat(fd_dir, &st) < 0) {
fprintf(2, "[!] fstat() failed\n");
close(fd_dir);
exit(1);
}
if (st.type != T_DIR) {
fprintf(2, "[!] %s is not a directory\n", InitDir);
fprintf(2, "Usage: find [target_dir] [file_name]\n");
close(fd_dir);
exit(1);
}
while (read(fd_dir, &de, sizeof(de)) == sizeof(de) && de.name[0]) {
if (!strcmp(de.name, ".") || !strcmp(de.name, ".."))
continue;
stat(de.name, &st);
if(!strcmp(de.name, FileName) && st.type == T_FILE){
printf("%s/%s\n", InitDir, FileName);
}
printf("de.name: %s\nst.type: %d\n", de.name, st.type);
if (st.type == T_DIR) {
if (!fork()) { // child
strcpy(CurDir, InitDir);
CurDir[strlen(CurDir)] = '/';
strcat(CurDir, de.name);
printf("[TEST] CurDir: %s\n", CurDir);
find(CurDir, FileName);
}
else { // parent
wait(0);
}
}
}
close(fd_dir);
exit(0);
}
int main(int argc, char* argv[]) {
if (argc != 3) {
fprintf(2, "Usage: find [target_dir] [file_name]\n");
exit(1);
}
find(argv[1], argv[2]);
exit(0);
}
^^^^^^ 오류 발생해서 애썼던 코드. Line 46에서 stat() 사용 시 경로를 제대로 못 줘서, Directory인데도 st.type이 T_FILE로 나왔었음
-> 이전에는 stat()의 path에 "aa"가 들어갔지만, <--> "./a/aa"와 같이 들어가도록 수정 후, 해결 됨
===========================================
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
Init command line for convenience
echo > b; mkdir a; echo > a/b; mkdir a/aa; echo > a/aa/b
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/fs.h"
__attribute__((noreturn)) void find(char* InitDir, char* FileName) {
int fd_dir; // fd for Directory
char Buf[512] = { 0, };
char *p;
struct stat st;
struct dirent de;
if ((fd_dir = open(InitDir, 0)) < 0) {
fprintf(2, "[!] failed to open %s\n", InitDir);
close(fd_dir);
exit(1);
}
if (fstat(fd_dir, &st) < 0) {
fprintf(2, "[!] fstat() failed\n");
close(fd_dir);
exit(1);
}
if (st.type != T_DIR) {
fprintf(2, "[!] %s is not a directory\n", InitDir);
fprintf(2, "Usage: find [target_dir] [file_name]\n");
close(fd_dir);
exit(1);
}
strcpy(Buf, InitDir);
p = Buf+strlen(Buf);
*p++ = '/';
while (read(fd_dir, &de, sizeof(de)) == sizeof(de) && de.name[0]) {
if (!strcmp(de.name, ".") || !strcmp(de.name, ".."))
continue;
memmove(p, de.name, DIRSIZ);
p[DIRSIZ] = 0;
stat(Buf, &st);
if(!strcmp(de.name, FileName) && st.type == T_FILE){
printf("%s\n", Buf);
}
if (st.type == T_DIR) {
if (!fork()) { // child
find(Buf, FileName);
}
else { // parent
wait(0);
}
}
}
close(fd_dir);
exit(0);
}
int main(int argc, char* argv[]) {
if (argc != 3) {
fprintf(2, "Usage: find [target_dir] [file_name]\n");
exit(1);
}
find(argv[1], argv[2]);
}
'xv6:2024 > Chapter 1' 카테고리의 다른 글
Exercise 1-5. xargs (1) | 2024.11.19 |
---|---|
Exercise 1-3. primes (0) | 2024.11.16 |
Exercise 1-2. pingpong (0) | 2024.11.16 |
Exercise 1-1. sleep (0) | 2024.11.16 |
xv6's every system call && read() from the pipe (1) | 2024.11.16 |