Linux/Linux_Source

Linux 간단한 ls 디렉토리 출력 프로그램 구현

sosal 2009. 11. 1. 12:10
반응형

/*
 http://sosal.tistory.com/
 * made by so_Sal
 */


LINK <-- Find 프로그램 소스입니다.
위 링크에선 아래 ls 프로그램에서 사용하는
DIR, dirent, stat 구조체에 대해서 자세히 설명하고 있습니다.
이 페이지에서는 위 3개의 구조체에 대해서 설명이 없습니다.
더 자세한 내용은 링크로..


/*
 * 옵션은 구현하지 않았고, 파일이 디렉토리만 구분합니다.
 * argv[1]에 위치값을 넣어야 합니다.
 * 연습용으로 아주 간단하게 만든 프로그램이라.. 허접합니다 ㅠㅠ
 * 재귀적인 방법을 사용합니다.
 */


// ls.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<dirent.h>
#include<sys/stat.h>

void _ls(char* pos,int depth);

int main(int argc,char* argv[]){
    if(argc>2){
        perror("Usage :: _ls [Directory] \n");
        exit(EXIT_FAILURE);
    }

    char* position;
    position = argv[1];   // 메인함수는 디렉토리 목록을 출력할 위치를
    _ls(position,0);        // 인자로 받아 _ls 함수의 매개변수로 전달하는 일만 수행합니다.
    exit(0);
}

void _ls(char* pos,int depth){  //depth는 처음 0이고, 디렉토리 출력중 새로운 디렉토리를 만나면
                                           //depth를 증가시켜 재귀적으로 함수를 다시 호출합니다.

    DIR *dp;                 // 실제 파일을 가리키는 포인터
    struct dirent *dir;     // 포인터가 가리키는 정보(i-node, name 등..)를 저장하는 구조체
    struct stat stat;        // device, uid, gid, size, time 등등 더 자세한 내용을 담는 구조체

    if( (dp=opendir(pos)) == NULL){
        perror("Can not open directory..\n");
        exit(EXIT_FAILURE);
    }
    chdir(pos);   //_ls에 넘겨진 위치인자 pos로 이동

    while(dir = readdir(dp)){
        memset(&stat,0,sizeof(struct stat));
        lstat(dir->d_name,&stat);  //dirent 구조체를 이용하여 아래 목록들을 출력합니다.
        if(S_ISDIR(stat.st_mode)){  //만약 디렉토리라면
            if(strncmp(".",dir->d_name,1) == 0 ||
                    strncmp("..",dir->d_name,2) == 0) //.과 ..은 출력x
                continue;
            printf("%*s%s/ \n",depth,"",dir->d_name);
            _ls(dir->d_name,depth+4);  //디렉토리라면 그 안으로 또 들어갑니다. 재귀형식입니다.
        }
        else
            printf("%*s%s \n",depth,"",dir->d_name);
    }
    closedir(dp);
}