ls 명령어 구현 2단계, ls -alR 구현, 디렉토리 정보 출력-3

IT/프로그래밍 과제



2013/05/10 - [Programming/프로그래밍 과제] - ls 명령어 구현 2단계, ls -alR 구현, 디렉토리 정보 출력-2


2013/05/05 - [Programming/프로그래밍 과제] - ls 명령어 구현 2단계, ls -alR 구현, 디렉토리 정보 출력-1


지난 포스팅에서 간략하게 필요한 알고리즘과 동작 방식에 대해

대충 알아보았었는데, 이번 포스팅에선 직접 살펴보고 구현해 볼 것이다.

(아래 파일 다운로드를 할 수 있다.)


먼저 하위 디렉토리를 탐색하기 위해선, 

우선 디렉토리인자 판별하는 구문이 필요하다.


디렉토리 오픈 후, readdir 함수와 lstat 함수를 통해 파일들을 읽어 저장 한 뒤에

stat 구조체의 st_mode로 구별하면 쉽게 디렉토리인지 판별이 가능하다.


하지만, 지난 ls 명령어 구현에서 Info_st라는 사용자 구조체에 이미 파일에 대한 정보가 저장 하도록 구현했으니, 구조체에 저장된 정보로 판별하도록 코딩을 해 볼 것이다.


구조체에 저장된 정보로 디렉토리 인지 판별은 파일 퍼미션의 첫자리가 'd'이면 디렉토리이다. 그리고 현재와 상위 디렉토리를 제외하기 위해서 "." ".."을 제외시켜야 한다. 이유는 현재 디렉토리에서 하위 디렉토리를 찾기 위함이다.


이를 간단히 코딩해 보면, 

이 if문을 해석해 보면 사용자 구조체의 퍼미션 첫째자리가 'd'이고

사용자 구조체 파일이름이 ".." "."이 아니면 이다.


즉, 디렉토리 일때만 실행되게 한 것이다.


이제 사용자 구조체에 정의되어 있는 파일이름에 해당하는 path를

디렉토리를 탐색하는 함수에 인자로 넣어주어 호출하기면 하면 재귀적으로 동작 할 것이다.


하지만, 이 path를 만드는데 고민이 필요했었는데. 이유는 lstat으로 불러온 정보는

파일 이름만 있었기 때문에 파일 이름만 넘겨주면 path가 완성되지 않았었다.


이를 고치기 위해서 생각한 방법이 디렉토리 탐색 함수의 인자로 받은 path 뒤에

lstat으로 불러온 파일 이름을 이어 붙여주면 된다.


이동작을 수행하기 위해 ls -al 과제1 이후에 새롭게 추가된 함수가 있는데 바로

ReadPathAndFilenameCpy 함수이다. 원형과 내용을 살펴보도록 하자.

디렉토리 탐색함수의 인자인 dirname과 filename이란 char 포인터를 인자로 받는다.

filename은 lstat으로 얻은 파일 이름을 가리키는 포인터 이다.


함수를 살펴보면,

메모리 소비를 줄이기 위해 고정 버퍼를 사용하는게 아니라,

할당을 통해 동적으로 메모리를 할당하는 것을 볼 수가 있다.


만약 처음 지장한 maxPathLen크기보다 path가 커진다면 ExtenMem 함수를 통해서

메모리를 realloc함수를 통해 크기를 늘리게 된다. 


함수에 대해 간단히 설명하자면, 첫번째 while문에서 dirname을 복사하고,

if문을 통해 '/'을 어이 붙여준다. 그런 뒤 filename을 그 뒤에 이어 붙여주어서

절대Path를 반환하는 함수이다.


예를 들어 함수를 호출할 때,

dirname이 /etc이고 filename이 Consolekit이라면

함수를 통해 반환되는 path는 /etc/Consolekit 이라는 path가 만들어 진다.

이 path를 통해 다시 디렉토리탐색 함수의 인자로 넣어주면 반복적인 동작을 통해

하위 디렉토리까지 전부 탐색 출력하는 프로그램을 만들 수 있다.


ReadPathAndFilenameCpy처럼 ls -al 명령어 1단계 이후 새롭게 추가 된 함수가 있는데

ExtenMem 함수와 ReadString이라는 함수가 있다. 

ExtenMem함수는 위에 설명했듯 realloc을 통해 메모리를 재 확장하는 함수이고,

ReadString함수는 처음 디렉토리 path를 고정버퍼가 아닌 동적 할당을 통해 메모리 손실을 없애고자 만든 함수이다. 

함수는 동작원리는 ReadPathAndFilenameCpy와 비슷하니 이해하기가 쉬울 것이다.


작성한 프로그램 실행사진을 살펴보겠다.


명령어를 입력하면, 아래와 같이 하위디렉토리가 출력 되는 것을 볼 수 있다.

아래 작성한 코드를 다운 받을 수 있도록 해 두었습니다.

궁금하신 점이나, 문의가 있으시면 댓글 혹은 메일 주시면 답변 드리겠습니다.


위 코드는 제가 작성한 코드로 프로그램 코딩 및 정보 교환을 목적으로 

공유하니, 상업적인 용도로 사용하지 말아주셨으면 좋겠습니다.


그리고 저 또한 부족한 점이 많으니 좀 더 개선 될 수 있는 방향을 제시해 주신다면,

개선해 나가도록 노력하겠습니다. 감사합니다.


자세한 사항은 파일에 주석 처리 하도록 하겠습니다.



※ 다운로드 file

hw2.c

list.c

list.h

user.h