728x90
이 문제는 MIT의 xv6 수업에 출처가 있습니다.
Write a simple version of the UNIX find program: find all the files in a directory tree with a specific name. Your solution should be in the file user/find.c
find <path> <target> 명령어를 구현하는 문제이다.
find 명령어를 실행하면 path의 디렉토리에 들어있는 모든 파일(디렉토리 포함)을 검사하여 target과 동일한 이름을 가진 파일의 경로를 모두 출력한다.
사전 지식)
구조체 dirent
struct dirent{
long d_ino; //inode 번호
off_t d_off; //offset
unsigned short d_reclen; //d_name 길이
char d_name[NAME_MAX+1]; //파일 이름
};
디렉토리를 나타내는 구조체이다.
구조체 stat
//stat.h
#define T_DIR 1 //Directory
#define T_FILE 2 //File
#define T_DEVICE 3 //Device
struct stat {
int dev; //File system''s disk device
uint ino; //Inode number
short type; //Type of file
short nlink; //Number of links to file
uint64 size; //Size of file in bytes
}
파일의 상태를 나타내는 구조체이다.
이를 이용하여 해당 파일이 디렉토리인지를 판별할 것이다.
xv6는 디렉토리또한 파일로 취급하여 readdir함수가 아닌 read함수로 읽는다.
Solution
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/fs.h"
#include "kernel/fcntl.h"
//경로를 제외한 파일명 리턴, ls.c에서 가져옴
char* fmtname(char *path){
char *p;
// 맨 마지막 슬래쉬로
for(p = path+strlen(path); p >= path && *p != '/'; p--)
;
//슬래쉬 다음으로 이동
p++;
return p;
}
void find(char *path, char *target){
char buf[64];
char *p;
int fd;
struct dirent dir;
struct stat st;
//target 문자열과 파일명이 같으면 출력
if(!strcmp(fmtname(path),target)){
printf("%s\n",path);
}
fd = open(path,0) //파일 읽기 전용 오픈
fstat(fd,&st); //파일 상태 확인
//파일이 디렉토리가 아닐 경우
if(st.type != T_DIR){
close(fd);
return;
}
//buf에 path+/
strcpy(buf,path);
p = buf+strlen(buf);
*p++ = '/';
while(read(fd,&dir,sizeof(dir))){
if(dir.inum == 0){
continue;
}
//p 뒤에 파일 이름 붙이기
memmove(p, dir.name, DIRSIZ);
p[DIRSIZ] = 0;
//파일명 .이거나 ..일 때 예외처리
if(!strcmp(dir.name,".") || !strcmp(dir.name,"..")){
continue;
}
find(buf,target);
}
close(fd);
}
int main(int argc, char *argv[]){
if(argc <= 2){
printf("Usage: find <path> <filename>\n");
exit(1);
}
find(argv[1],argv[2]);
exit(0);
}
728x90
'운영체제 > xv6' 카테고리의 다른 글
xv6 Lab: Utilities (5) xargs (0) | 2022.09.03 |
---|---|
xv6 Lab: Utilities (3) primes (0) | 2022.09.01 |
xv6 Lab: Utilities (2) pingpong (0) | 2022.08.31 |
xv6 Lab: Utilities (1) sleep (0) | 2022.08.31 |