디렉토리


  • ● 디렉토리란? 파일 이름들의 집합으로, 파일들을 논리적으로 관련 그룹별로 나누어주는 수단을 제공한다. 디렉토리는 파일뿐 아니라 다른 디렉토리를 토함할 수 있으며, 계층적인 트리 구조를 거꾸로 놓은 것과 같이 묘사될 수 있다.

어떤 디렉토리이든 맨 위에는 루트 디렉토리라 불리는 하나의 디렉토리가 있다. 

이것은 '/' 라는 기호를 사용하여 표현하며, 트리의 단말 노드들은 보통 파일, 특수 파일, 빈 디렉토리이다.

  • ● 현재 작업 디렉토리란? 로그인한 사용자는 현재 작업 디렉토리라고 불리는 파일 구조의 특정한 장소에서 작업을 하게 되는데, 초기 설정 값은 그 사용자의 홈 디렉토리이다.

디렉토리 구조

구조적으로 디렉토리는 일련의 디렉토리 항으로 구성된다.

각 디렉토리항은 최소한 다음과 같이 구성된다.



 i-node 번호


파일 이름을장하는 문자 필드 


i-node 번호는 한 파일을 유일하게 식별한다. 

i-node 번호는 i-node 구조라 불리는 파일에 대한 모든 정보를 저장하고 있는 자료구조를 찾기 위해 운영체제에 의해 사용된다.


점(.)과 이중점(..)


모든 디렉토리 안에는 점(.)과 이중점(..)이라는 이상한 파일이름이 들어가있다.


사실 점(.)현재 디렉토리를 의미하고, 이중점(..)은 현재 디렉토리의 부모 디렉토리를 가리키는 표준 표기법이다.

즉, 현재 디렉토리와 부모 디렉토리에 대한 링크인 것이다!


디렉토리 허가


보통 파일과 같이 디렉토리도 소유자, 소유자와 같은 그룹의 사용자들, 그 외 사용자들에 대한 접근 허가를 가진다.

표기법도 보통 파일과 같이 표현하지만, 조금은 다르게 해석된다.

  • ● 디렉토리에 대한 읽기 허가 : 디렉토리 내에 있는 파일이나 부디렉토리의 이름을 리스트할 수 있음을 뜻한다. 그러나 각 파일 자체에 저장된 정보를 읽을 수 있다는 것은 아니다. 즉, 디렉토리내 각 파일은 각 파일의 독립된 접근 허가에 의해 제어된다!
  • ● 디렉토리에 대한 쓰기 허가 : 디렉토리 내 기존의 파일을 제거하고 같은 이름의 새로운 파일을 만들 수 있음을 뜻한다. 그러나 파일의 내용을 변경시킬 수 있다는 것을 뜻하지는 않는다.
  • ● 디렉토리에 대한 실행 허가 : 탐색 허가로도 불리며, chdir 시스템 호출을 사용하여 사용자가 디렉토리 내부로 들어가는 것을 허용한다. 파일을 열거나 프로그램을 실행시키기 위해서는 각 파일의 독립된 접근 허가에 따른다.

디렉토리와 시스템 호출

디렉토리를 조작하기 위해서서는 앞서 배운 보통 파일과는 다른 시스템 호출을 이용해야 한다.
즉, creat나 open 시스템 호출의 사용이 불가능하다.
이러한 제약 조건은 write를 사용해서 디렉토리를 변경하는 것을 막기 위해서이다.

  • ● 디렉토리의 생성
#include <sys/types.h>
#include <sys/stat.h>

int mkdir(const char *pathname, mode_t mode);


첫 번째 인수는 생성될 디렉토리의 경로이름이고, 두 번째 인수는 접근 허가 집합이다.


int retval;

retval = mkdir("/tmp/dir", 0777);


디렉토리의 생성에 성공하면 0을 반환하고, 실패시 -1을 반환한다.


mkdir은 새로 생성된 디렉토리에 두 개의 링크 '.'(점)과 '..'(이중점)을 넣는다.

만약 이 두 개의 링크가 존재하지 않으면 그 항은 디렉토리로 사용할 수 없을 것이다!


  • ● 디렉토리 제거
#include <unistd.h>

int rmdir(const char *pathname);


디렉토리를 제거하고 싶을 경우 rmdir 시스템 호출에 파라미터로 제거할 디렉토리 경로를 입력하여 주면 된다.

이 호출은 디렉토리가 비어있을 경우(단지 .과 ..만을 포함할 경우를 말한다!!)에만 성공적이다!


● 디렉토리 열기

#include <sys/types.h>

#include <dirent.h>


DIR *opendir(const char *dirname);


opendir의 인수는 개방할 디렉토리의 경로이름이다.

만약 성공적으로 개방한다면, 이 호출은 DIR 유형에 대한 포인터를 반환한다.

헤더파일 <dirent.h>에 하나의 디렉토리 스트림을 나타내는 DIR 유형에 대해 정의되어있다.


열려고 하는 것이 디렉토리이기 때문에 처음 open하면(성공시) 디렉토리 스트림에 대한 포인터가 디렉토리의 첫 항에 위치한다.

만약 호출에 실패하면 시스템은 널(null) 포인터를 반환한다!

그러므로 오류 검사코드는 널 포인터인지 아닌지를 검사해야할 것이다!


● 디렉토리 닫기

#include <dirent.h>


int closedir(DIR *dirptr);


closedir 시스템 호출은 인수가 가리키는 디렉토리 스트림을 닫는다.


● 디렉토리 읽기

#include <sys/types.h>

#include <dirent.h>


struct dirent *readdir(DIR *dirptr);


readdir 시스템 호출은 opendir을 통해 얻은 디렉토리 스트림 포인터를 파라미터로 받는다.

이렇게 개방된 디렉토리를 readdir을 통해 읽으면 첫 호출에 의해 디렉토리의 첫 항이 struct dirent로 읽혀 들여진다.

호출이 끝나면, 디렉토리 포인터는 다음 항으로 이동해 있을 것이다.

그렇게 읽고 난 후 디렉토리의 끝 항에 도달하면 널 포인터를 반환하게 된다.


여기서, 디렉토리를 처음부터 다시 읽고 싶다면 다음과 같은 시스템 호출을 사용하면 된다.


#include <sys/types.h>

#include <dirent.h>


void reinddir(DIR *dirptr);


rewinddir 호출은 첫 항으로 돌아가길 원하는 디렉토리 스트림 포인터를 파라미터로 받는다!


다음 예는 개방한 디렉토리 내의 모든 디렉토리항 이름을 출력한다. (i-node 번호가 유효한지 검사하면 된다.)


..

...

while( d = readdir(dp) ) { // opendir로 dp를 얻었다고 가정

if( d->d_no != 0 )

printf("%s \n", d->d_name);

}

...

..






'개발 > System' 카테고리의 다른 글

임베디드 스케치 공부  (0) 2019.11.19
특정 파일 UTF8 ↔ ANSI 변환  (0) 2013.08.24
파일 정보의 획득  (0) 2012.10.29
다수의 이름을 갖는 파일  (0) 2012.10.29
access, chmod, chown 시스템 호출  (0) 2012.10.29

+ Recent posts