Linux/Linux_programing

Linux - dirent.h 함수와 구조체, find 프로그램 맛보기

sosal 2010. 1. 20. 01:00
반응형

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

이번 포스팅에서 다루는 내용
  ::  DIR *opendir(const char *dirname);
  ::  int readdir(unsigned int fd, struct dirent *dirp, unsigned  int count);
  ::  int getdents(unsigned int fd, struct dirent *dirp, unsigned int count);
  ::  struct dirent
  ::  int closedir(DIR *dir);




#include<sys/types.h>
#include<dirent.h>

DIR *opendir(const char *dirname);

opendir() 함수는 매개변수 dirname에 해당하는 디렉토리 스트림을 열고,
그 디렉토리 스트림에 대한 포인터를 반환합니다.
포인터가 가리키는 디렉토리의 첫번째 항목을 가리킵니다.




#include<unistd.h>
#include<linux/dirent.h>
#include<linux/unistd.h>


int readdir(unsigned int fd, struct dirent *dirp, unsigned  int count);

위 함수는 이미 바뀐 예전 커널시스템 콜 인터페이스를 위해
manual에 존재하는 내용이며, 위 함수의 사용은 getdents() 가 대신하고 있다.
    (하지만 개인적으로는.. 대부분의 ls 프로그램에서는 readdir()을 쓰더군요)
readdir() 함수는 파일 서술자 fd에 의해 지목된 디렉토리에서
dirp에 의해 포인트된 메모리 지역에 있는 dirent 구조체를 읽어, DIR*에 저장한다.
(3번째 매개변수 count는 무시된다.)
count 인자는 메모리 공간의 크기이지만, 무시 가능하다.




#include <unistd.h>
#include <linux/types.h>
#include <linux/dirent.h>
#include <linux/unistd.h>


int getdents(unsigned int fd, struct dirent *dirp, unsigned int count);

getdents() 함수는 파일 서술자 fd가 가리키는 디렉토리에 존재하는
파일, 디렉토리들에서 부터 dirent 구조체를 읽어와, DIR*가 가리키는 메모리 공간에 저장한다.
count 인자는 메모리 공간의 크기이지만, 무시 가능하다.
매개변수는 readdir과 일치한다.





#include<dirent.h>

dirent 구조체는 다음과 같이 선언된다.
 struct dirent
{
    long d_ino;                                /* 아이노드 */
    off_t d_off;                                 /* dirent 의 offset */
    unsigned short d_reclen;            /* d_name 의 길이 */
    char d_name [NAME_MAX+1];   /* 파일 이름(없다면 NULL로 종료) */
}

dirent 구조체는 파일, 또는 디렉토리가 가지고 있는 정보 구조체이다.

d_ino :: 는 파일이 가지고 있는 자신만의 번호 inode를 가리키는 숫자이다.
d_off  :: 는 디렉토리의 시작에서 dirent까지의 거리를 말한다.
d_reclen :: 파일 혹은 디렉토리의 이름의 길이이다. (NULL을 포함하지 않는다.)
d_name :: 파일 혹은 디렉토리의 이름이다. (NULL이라면 파일 없음을 의미)

return :: 성공 : 1, 실패 : -1.


#include <sys/types.h>
#include <dirent.h>

int closedir(DIR *dir);

closedir() 함수는 dir과 연관된 디렉토리 스트림을 닫습니다.
디렉토리 스트림 서술자 dir은 위 함수 호출 이후에는 유효하지 않습니다.
return : 성공시 0, 실패시 -1


===================================== 예제 =====================================

/*
 * 이 예제는, 매개변수를 받아, 현재풀더 "  . " 에 매개변수와 같은 이름의 파일이 있는지 검사하여
 * 있다면 found argv[n], 없다면 failed to find argv[n]을 출력하는 프로그램입니다.
 * 아래 예제에서 사용된 함수들에 대한 설명은 모두 위에서 찾아보실 수 있습니다.
 */



#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>

static void lookup(const char *arg);

int main(int argc, char *argv[])
{
    int i;
    for (i = 1; i < argc; i++)
        lookup(argv[i]);      // 프로그램에 매개변수로 넘어간 문자열을 검색하는 루틴으로 보냄
    return (0);
}

static void lookup(const char *arg)
{
    DIR *dirp;
    struct dirent *dp;


    if ((dirp = opendir(".")) == NULL) {        //  " . " 은 현재위치 디렉토리를 뜻하며,
        perror("couldn't open '.' \n ");        // dirp라는 DIR *형 변수에 현재디렉토리의
                                                           // 첫번째 항목을 가리키도록 합니다.

        return;
    }


    do {
        errno = 0;
        if ((dp = readdir(dirp)) != NULL) {       //dirp가 가리키는 항목에 대한 정보를 가져옵니다.
            if (strcmp(dp->d_name, arg) != 0)  //dp는 dirent 구조체이며, 
                continue;                                 // inode, d_name 등의 정보를 가집니다.


            (void) printf("found %s\n", arg);
            (void) closedir(dirp);                      //
                return;


        }
    } while (dp != NULL);


    if (errno != 0)
        perror("error reading directory");
    else
        (void) printf("failed to find %s\n", arg);
    (void) closedir(dirp);
    return;
}