본문 바로가기

xv6:2024/Chapter 1

Exercise 1-4. find

[!] 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