[시스템 프로그래밍] Chapter 5

2024. 5. 8. 17:37·Computer Science/시스템 프로그래밍

Files and Directories

OS는 파일시스템 안에서 물리적인 디스크를 관리한다.

File system : 파일과 attribute의 집합체로 파일을 효율적으로 관리하기 위해서 파일의 위치나 이름을 관리함. 실제 하드디스크상의 위치는 모르더라도 파일이름과 offset으로 파일의 위치를 찾는다

Directory : 다른 파일이나 서브디렉터리들을 포함할 수 있는 기능을 가지고 있는 것. 아이노드 번호와 파일명을 하나의 디렉터리 엔트리라고 하고 이정보를 가지고 있는 것을 디렉터리라고 한다. 대부분의 디렉터리는 트리구조이다.(계층구조)

가장 최상단 디렉토리를 루티티렉토리라고 하고 다른 서브디렉토리는 루트디렉토리의 자식이나 자손 노드로 포함된다. dirA에는 파일이나 다른 서브디렉토리가 포함될 수 있다.

Root directory : ' / '라고 표현함. 절대경로(루트부터 시작되는 경로)를 의미함. 

Parent directory : " .. " 현재 작업 중 인디렉토리를 기준으로 부모디렉터리를 표현함.

Current working directory : " . " 현재 작업 중인 디렉터리를 나타냄.

Home directory :  " ~ "로그인하고 처음에 보이는 디렉토리가 홈 디렉터리임 ex) cd ~

Sub-directory :  다른디렉토리안에 속해있는 디렉터리


pathname

루트부터 시작하는 절대경로(absolute path) or 현재 작업디렉터리를 기준으로 경로를 나타내는 상대경로(relative path)라는 두 가지 path로 이름 지을 수 있음

absolute path는 또 다른 말로 fully qualified path

절대경로는 루트부터 시작하기에 /부터 시작한다,

상대경로는 현재 작업 디렉터리를 기준으로 파일의 위치를 나타내므로 현재 디렉터리가 어디냐에 따라 최종 경로가 달라질 수 있음.

만약에 dirA에서 my3.dat의 경로를 상대경로로 나타낸다면?../dirC/my3.dat

만약에 dirA에서 my3.dat의 경로를 절대경로로 나타낸다면? /dirC/my3.dat

만약에 dirB에서 dirA에 있는 my1.dat의 경로를 상대경로로 나타난 대면?../my1.dat or./../my1.dat

이처럼 상대경로로 나타내는 방법은 다양하나 short path로 보통 표현한다.

만약에 dirB에서 dirA에 있는 my1.dat의 경로를 절대경로로 나타난 대면? /dirA/my1.dat

 

Change directory 

cd 명령어처럼 사용이 되는 함수가 있다. chdir

내가 옮기려고 하는 파일 경로를 파라미터로 지정하게되면 이동한다. 성공하면 0 실패시 -1을 리턴한다. 이 함수는 현재 작업디렉토리에서만 영향을 끼친다.
현재 작업디렉토리가 어디인지는 모르겠지만 현재 작업디렉토리를 /tmp로 변경해달라고 요청하는것
리눅스에서 현재 작업디렉토리의 경로를 확인하고 싶을때 pwd를 사용했다. 프로그램 안에서 현재 작업디렉토리의 경로를 알고 싶을때 getcwd함수를 사용하자.첫번째 파라미터는 스트링을 담는 파라미터, 즉 현재 작업디렉토리를 첫번째 파리미터 버퍼에 써준다. 그리고 그 크기를 2번째 파라미터에 넣어준다. 이 함수의 리턴값으로 성공할 경우에 버퍼의 포인터값이 리턴되기도 한다. 실패할 경우에 NULL값이 리턴이 된다.

getcwd함수를 사용하러면 버퍼를 준비해야 하는데, 그럼 버퍼의 크기를 얼마로 해야 할까? 시스템에서 반환할 수 있는 최대 경로를 알아야 버퍼의 크기를 설정할 수 있는데 알아내기 쉽지 않고 임의로 설정하는 것도 어려움. 

그럼 시스템 별로 PATH_MAX가 정해져 있는데 이것을 활용을 하자. 그래서 char buf [PATH_MAX];로 선언하자. PATH_MAX가 없는 시스템인 경우엔 임의의 값으로 사용하자.

버퍼의 이름을 mycwd로 하고 어레이의 크기를 path_max로 선언함, 그런데 path-max가 없는 경우도 있기에 확인을 해야하는데 위에 빨간 내용을 보자. #ifndef 만약에 path-max가 정의되있지 않으면 밑에 255로 정의를 하자. 만약에 시스템에 path_max가 정의되어있다면 define식은 건너뜀

search path

만약 실행파일의 이름만 주게 되면 OS 프로세스는 사용자가 준 실행파일의 위치를 시스템의 환경변수 중에서 PATH에 정의된 디렉터리를 순서대로 뒤져서 찾아낸다.

which 명령어를 써서 실행파일의 위치를 바로 알아낼 수 있다. ex) which ls 

현재 작업디렉터리를 PATH환경변수에 추가할때 맨 처음에 둔다면 보안상 위험할 수 있음. 왜? 해커가 home디렉토리에 ls라는 이름의 실행파일을 넣어두고 심어두고 나간다고 가정하자. 사용자가 ls를 입력하고 엔터를 치면 시스템이 ls라는 파일을 찾기 위해서 PATH환경 변수를 쭉 뒤진다, 근데 . 이라는 현재디렉토리가 맨처음에 뒤져진다면 현재 디렉토리에 해커가 심어둔 ls파일이 실행이 된다. 그렇게 때문에 현재 디렉토리를 맨 마지막에 둔다면 이런 위험성을 줄일 수 있다.


Directory access

디렉터리안에있는 내용들을 access하고 싶을때 opendir, closedir, readdir함수가 있다.

opendir을 사용하기위해서 두가지 헤더파일을 include하자. 오픈하려고하는 디렉토리의 경로를 파라미터로 주자. 성공적으로 오픈이 되면 오픈된 디렉토리 목록정보를 가지고 있는 데이터 스트럭쳐의 포인터값이 리턴이 된다 그것이 DIR이다. DIR은 dirent.h안에 정의된 타입이고, 디렉토리 스트림이란것을 표현하는 데이터 스트럭쳐다. 디렉토리 스트림은 타깃 디렉토리안에 들어 있는 모든디렉토리 엔트리들의 시퀀스를 디렉토리 스트림이라고 한다.그 디렉토리 스트림을 표현한 데이터 스트럭쳐가 DIR이다.
디렉토리 엔트리란 inode번호와 파일명의 정보이다.

성공적으로 오픈을 했다면 DIR스트림을 가지고 디렉토리 엔트리를 access 할 수 있다.

readdir함수를 가지고 디렉토리 엔트리를 access할 수 있다. readdir함수의 파라미터는 DIR포인터 값이다. 이 값은opendir함수의 리턴값이 였다.이 함수를 호출하면 첫번재 디렉토리 엔트리가 struct dirent * 형태로 호출되고 두번째로 이 함수를 호출하면 두번째 디렉토리 엔트리가 반환인 된다. readdir의 리턴값이 dirent라는 구조체의 포인터값으로 반환이 된다. 하나의 디렉토리 엔트리를 나타내는 데이거 스트럭쳐를 dirent 구조체이다. readdir함수는 보통 반복문안에서 순차적으로 탐색하는식으로 많이 사용한다. 예를 들어서 while문안에서 readdir함수를 반복적으로 호출을 하는데 file의 end of file에서 호출을 하게 되면 NULL값이 반환이 된다. 그래서 리턴값이 NULL이 아닐때까지 반복적으로 readdir함수를 호출해서 디렉토리엔트리를 읽을 수 있다.
다 사용하면 오픈했던 디렉토리를 닫기 위해서 closedir함수를 호출하면 된다. 타깃디렉토리를 오픈하고 난 뒤에 readdir을 할 때마다 내부적으로 포인터가 있어서  이포인터가 값이 하나씩 이동을 해서 다음 엔트리 구조체가 리턴이 된다. 이떄 rewinddir함수를 호출하면 이 포인터를 다시 처음으로 되돌리는 역할을 한다. 그 다음 다시 readdir함수를 호출하면 첫번째 디렉토리 엔트리가 반환이된다.
readdir함수를 호출하면 첫번쨰 디렉토리 엔트리가 반환이되고 포인터는 하나 내려오게 된다. 또 readdir함수를 호출하면 두번째 디렉토리 에느리가 반환이되고 포인터는 하나 내려온다. 여기서 rewinddir함수를 호출하면 내부 포인터값이 처음으로 되돌아 간다.
간단하게 ls명령어를 구현한 예제이다. 이 프로그램을 실행할때 두번째 argv로 타깃디렉토리를 지정함, opendir함수로 사용자가 준 타깃디렉토리를 오픈하면 dirp라는 포인터타입을 반환한다. 이포인터를 가지고 디렉토리 엔트리를 엑세스할 수 있다. readdir함수에 이 포인터값을 넘겨줘서 호출을 하면 첫번쨰 디렉토리 엔트리의 구조체가 반환이된다. direntp는 dirent의 구조체의 포인터임. readdir함수의 리턴타입이 dirent구조체의 포인터 타입이였다. 그래서 printf로 리턴된 디렉토리 엔트리 구조체가 가리키는 d_name(파일이름)를 출력을한다. null이 되면 모든 디렉토리를 읽었다는 뜻이니 빠져나와서 closedir을해서 타깃 디렉토리를 닫는다. 그래서 showname . 을 입력을하면 현재 디렉토리에 있는 파일들이 출력이된다.


File status information

lstat과 stat함수를 이용해서 파일의 여러 정보들을 얻어낼 수 있다. 

두함수 모두 첫번째 파라미터로 타깃파일의 경로명을 주고 시스템이 그 여러가지 정보들을 반환하는데 그것을 두번째 파라미터로 반환을 해준다. 만약에 첫번째 파라미터에 링크를 주면 어떻게 될까? stat함수에서 첫번째 파라미터에 링크를 주게 되면 링크가 가리키는 원본파일의 상태정보가 반환이된다. 링크파일자체의 상태정보를 얻고 싶다면 lstat함수를 쓰자.
파일 상태정보를 포함한 객체를 inode라고 한다. 파일을 생성할떄마다 파일의 내용을 담고 있는 inode객체가 생성이되고 이와같은 정보가 담겨있다.
스탯함수를 사용한 예제로 타겟파일의 상태정보를 두번째 파라미터로 반환을 받아서 이파일의 last access값을 출력을 한다. time타입값을 스트링으로 출력하기 위헤서 ctime함수를 사용해서 time타입의값을 스트링으로 변환을 할 수 있다. 그래서 시간값을 스트링으로 출력한다.
위의 예제는 st_mode라는 파일의 권한과 파일정보를 포함한 이 필드를 이용해서 이 파일이 디렉토리인지 아닌지 판단하는 간단한 예시이다. 파라미터로 타겟파일 경로를 주게되면 그 파일의 상태정보를 상태함수를 이용해서 알아오고 statbuf라는 구조체에 상태정보가 쓰여진다. 그러면 st_mode필드값을 탐색을 해야하는데 수동으로 하기에 어렵기 떄문에 이 타입을 조사하기위해서 매크로가 제공이 된다. S_ISDIR이라는 매크로는 st_mode가 디렉토리인지 확인하는 매크로이고 디렉토리라면 0이아닌값이 반환되고 티렉토리가 아니라면 0이 반환된다.
참고만 할것

Inode : 파일에 대한 정보를 담고 있는 객체, 아이노드의 크기는 파일의 크기와 상관없이 고정되어 있다.

아이노드안에는 이러한 정보와 구조로 이루어져있다. 크게보면 두가지 영역으로 볼수있다. 파일정보를 담고있는 영역과 파일의 포인터를 가지고있는 영역으로 나눠진다. 포인터의 종류도 구분이 된다. direct pointer는 파일의 블럭을 직접 가리킨다. indirect pointer는 간접적으로 파일의 블럭을 가리킨다. indirect 도 3가지의 종류가 있다. single indirect pointer는 한 단계를 거쳐서 파일 블록을 가리키는 포인터이고 double은 두단계, triple은 3단계를 거쳐서 파일 블록을 가리키는 포인터이다. 이게 뭔소리냐? single먼저 보면 single indirect pointer의 포인트 값이 어떤블록을 가리키는데 파일의 컨텐츠를 나타내는 것이 아니고 이 블럭안에는 다이렉트 포인터 값이 들어가 있다. 다이렉트 포인터값을 따라가면 실제 파일 블럭을 만나게 된다. 그래서 single indirect pointer로부터 다이렉트 포인터 블럭을 한단계 거쳐서 파일 블록으로 갈 수 있다. 이것이 sigle indirect pointer이다. 그럼 indirect pointer를 왜 쓰지? 파일의 크기가 큰경우에 파일블럭을 많이 가리켜야하기 떄문에 direct pointer로는 부족하기 떄문에.

Directory implementation

디렉터리안에 디렉토리 엔트리 정보가 들어가 있다. 디렉토리도 하나의 파일이다. 그래서 파일의 타입중에서 디렉토리 타입인 파일이 있다. 그럼 디렉토리파일은 어떤기능을 가지고 있나면 디렉토리 엔트리정보를 가지고 있는 파일이 디렉토리이다. 하나의 디렉토리 엔트리란 파일명과 파일위치 정보를 담고 있는 정보이다. 파일위치는 inode번호를 가지고 표현을 한다. 

디렉터리 안에는디렉토리 엔트리 정보가 들어가있다. 그래서 디렉토리 엔트리란 inode번호와 파일명의 페어로 구성이 된다. 

어떤 파일의 inode로 access 하기 위해선 사용자는 inode를 직접 지정하는 것이 아니고 사용자가 표현하기 쉽도록 경로명을 통해서 access 하고 싶은 파일을 지정을 하면 os가 사용자가 지정한 경로를 따라서 부모디렉터리부터 말단 디렉토리까지 쭉 내려가 파일명을 찾게되면 그 파일의 디렉토리 엔트리를 찾아갈 수 있게되는 것이고 디렉토리엔트리를 찾았으면 inode번호를 알게된다. 그래서 innode객체를 찾아갈수있게된다. inode객체를 찾아가면 그 파일의 상태정보와 파일의 내용을 access할 수 있게 된다. 

 

advantages of inode+filename

실제파일과 디렉토리 구조를 분리하면 어떤 장점이 있을까?
1. 파일명이 디렉토리 엔트리 안에 들어있기 때문에 파일명을 변경할 때 간단한다.(디렉터리 엔트리만 찾아가면 엔트리에 파일명 필드가 있어서 그 필드만 수정하면 된다. 실제 파일의 inode객체를 access 해서 수정할 필요가 없어짐)

2. 만약에 파일이 속한 디렉터리를 변경할때 실제 파일의 inode객체와 블럭들을 실제로 옮길 필요가 없고 디렉토리 엔트리만 옮기면 된다. 

3. 디스크상에 실제 파일은 하나만 존재하더라도 그 파일을 나타내는 파일이 름은 여러 개가 있을수 있다. 같은 inode를 가리키는 디렉터리 엔트리만 추가하면 되기떄문. 즉, 같은 파일을 가리키는 이름을 여러개 만들어서 사용할 수 있다. 그래서 서로다른 디렉토리에 같은 이름의 파일로 같은 파일을 가리킬 수 있다. 혹은 같은 디렉토리안에 서로 다른 이름을 가지고 있지만 그 다른이름이 같은 파일을 가리키게 만들수도 있다.

4. 디렉토리 엔트리 구조의 크기는 크지 않다. 왜냐하면 실제 파일정보는 inode라는 객체에 따로 저장이 되어있기 때문에 

 

inode의 객체가 128byte, 포인터는 4byte, 상태정보가 차지하는 공간이 68byte이고 블럭하나의 크기가 8kb라고 하자, 또한 블럭내의 포인터의 크기도 32bits(4byte)라고 가정한다면 이 inode객체안에 direct pointer가 몇개가 있을수 있을까?  우선 포인트라는 것은 direct와 indirect 두가지 종류가 있다. indirect는 또 3가지 종류가 있기떄문에 3x4 = 12 byte이다. 그래서 128-68-12 = 48byte이므로 direct pointer가 차지하는 공간은 48byte가 된다. 그렇기 떄문에 direct pointer의 개수는 48 ÷ 4 = 12개이다. 두번째 문제는 inode가 direct pointer를 가지고 얼마나 큰 파일 컨탠츠를 담을수 있을까? direct pointer하나가 파일블럭 하나를 가리키기 떄문에 12x8kb의 블록을 가리키게된다. 그래서 96kb크기의 파일 컨텐츠를 가질수가 있게 된다. 1kb = 2^10byte이고 1mb = 2^10kb = 2^20byte이고 1gb = 2^30b가되므로 8kb는 8x2^10byte = 8192byte가 되고 포인터의 개수는 총 12개이니 8192x12 = 98304bytes(96kb)가 답이된다. 하지만 96kb는 작은 크기이므로 큰 크기의 파일을 읽으려면 indirect pointer가 필요한 것이다.마지막 문제는 single indirect로 몇개의 파일블럭을 가리킬 수 있냐?이다. indirect pointer는 direct pointer의 개수만큼 파일 블록을 가리킬 수 있다.블록하나의 크기는 8kb이고 포인터의 크기는 4byte이므로 8x2^10을 4로 나누면 2048이 된다. 즉, 블럭안에 2048개의 direct pointer가 들어있다는 얘기이다. 그래서 single indirect poiner를 가지고 2048개의 파일블록을 가리킬 수 있게 된다. 파일의 블럭크기는 8kb이니까 8kb x 2048 = 8 x 2^10 x 2 x 2^10 = 16 x 2^20 = 16MB가 된다. 이러한 방식으로 double indirect pointer도 계산이 가능할 것이다.☆


Hard links and Symbolic Links

링크란 파일이름과 inode사이의 연관관계를 표현한 것이다. 

hard link : 파일이름과 inode사이의 연관관계가 강한 것(직접적인 연결)

symbolic link : 파일이름과 inode사이의 연관관계가 약한 것(간접적인 연결)

 

hand link 한 디렉터리 레퍼런스를 나타내는 것이고 하드디스크 상의 파일을 찾아갈 수 있는, 즉 inode를 찾아갈수있는 직접적인 포인터 정보를 가지고있는것이다. 파일과 연관된 파일명 이라는 것은 간단하게 디렉토리구조안에 포함된 레이블이라고 한다. 그냥 파일이름이라고 생각하면됨. 그리고 같은 파일을 가리키는 하드링크의 이름이 하나만 있는것이 아니라 여러개가 있을 수가 있다. 그 하드링크의 이름은 같은 디렉토리안에 다른이름으로 존재할 수 있고 다른 디렉토리에서 원본 파일 이름과 같은 이름으로 위치할 수 도있다. ex) 파일을 하나 만들면 inode가 만들어지고 디렉토리 엔트리도 생성된다. 그래서 inode 번호를 통해서 엑세스 할 수 있게된다. 근데 하드링크는 같은 inode를 가리키는 디렉토리를 또 만들 수 있다는 뜻이다. 즉, 같은 inode를 가리키는 하드링크의 이름이 여러개가 있을 수 있다. 같은이름일수도, 다른 이름일 수도 있고 이처럼 하드링크를 여러개 만들 수 있다. 심볼릭 링크도 마찬가지이다. 어떤 특정 디렉토리 엔트리를 통해서 파일을 변경을 한다고 가정하고 test`에 ABC라는 내용을 추가했다고 하자. 그 변경된 사항이 test라는 이름으로 access 하더라도 변경된 사항이 test`을 access 하지 않더라도 똑같이 적용이 된다. 왜냐하면 test나 test`이 같은 파일을 가리키고 있기 때문에. 이것은 씸볼릭도 마찬가지이다. 그러나 하드링크는 같은 파일시스템 내의 파일에 대해서만 참조할 수 있다는 제약사항이 있다. 

 

새로운 하드링크를 추가로 생성하게 되면 새로운 디렉터리 엔트리만 추가가 된다.새로운 디렉토리 엔트리는 같은 inode를 가리키기 때문에 inode번호가 동일하다. ln 명령어로 원본파일의 하드링크를 추가할 수 있다. 하드링크를 추가하면 링크 카운트값이 하나 증가된다(감소되면 하나삭제). 삭제하려면 rm 명령어를 사용하면 된다. ln 명령어와 똑같은 역할을 하는 system call 함수가 있는데 link함수이다. 반대로 삭제하려는 함수는 unlink함수이다. 하드링크를 삭제하다가 카운터 값이 0 이 되면 inode자체가 삭제된다. 

 

링크 카운터는 같은 파일을 가리키는 하드링크가 몇 개가 있는지에 대한 카운터값을 노드에 유지를 한다. 링크카운터는 정수형 숫자이고 int 값은 링크의 총개수를 알려주고 새로운 하드링크가 생성될떄마다 카운터 값이 하나씩 증가가 되고 링크가 삭제돼서 카운터값이 0이 되면 디렉터리 엔트리만 지우는 것이 아니라 inode자체도 지운다. 

첫번째 파라미터가 원본파일 경로명, 두번째 파라미터가 새롭게 만들어진 하드링크의 경로명이다. 삭제할때는 삭제할 파일의 경로명을 주면 된다.
위의 명령어를 그림으로 표햔한것이다. name1이 하드링크를 추가를해서 /dirB라는 디렉토리가 추가가 되었다.디렉토리의 이름은 name2이고 inode의 번호는 name1의 inode와 동일하다. 그래서 같은 inode를 가리키게 된다. 그래서 inode와 파일 블럭 사이에서는 변화가 없다. 변화된것은 링크 카운터가 2로 증가되었다. 그래서 name2라는 이름으로 파일내용을 변경하면 name1로 봤을때도 변경된 사항이 그대로 반영된다. 그래서 하드링크라는 것은 별다른 원본의 개념이 없다. name1도 원본 inode를 가리키고 name2도 원본inode를 가리킨다.

 

symbolic link는 특별한 타입의 파일이다. 씸볼릭링크를 추가를 하면 하드링크처럼 inode는 가만히 있고 디렉토리엔트리가 추가되는것이 아니라 심볼릭 링크를 하나 만들게되면 심볼릭 링크라는 원본파일의 경로명이 포함된 특별한 형태의 파일이하나 만들어진다. 

내가 access 하려고 하는 파일을 씸볼릭 링크의 경로로 주게 되면 OS가 심볼릭 링크에 inode를 보고 탐색을한다. 탐색을 해서 심볼릭 링크까지 가고 inode를 찾아간 다음에 이 파일이 일반파일이아니고 심볼릭 링크라는것을 파악하게 되면 디렉토리 탐색을 멈추는 것이 아니라 심볼릭 링크안에 포함되어 있는 원본파일을 보고 그 원본 파일의 inode로 탐색을 계속한다. OS가 심볼릭링크안에 원본파일의 경로가 있다는것을 보고 계속탐색을한다. 그래서 원본파일의 inode를 찾아간다. 그래서 심볼릭 링크를 통해서 간접적으로 연결된 원본파일을 찾아간다. 심볼릭링크를 만들기위해선 ln -s 명령어를 사용한다. 또한 심볼릭 링크는 하드링크처럼 원본파일의 링크 카운터값을 유지하지 않는다. 하드링크는 좀더 강한 직접적인 연관관계를 맺고 있는 링크이기때문에 inode에서 별도로 링크 카운터 값을 관리하는 반면에 심볼릭 링크는 카운트 값을 따로 관리하지 않는다. 

심볼릭링크를 만들기 위해서 쓰이는 system call 함수는 symlink함수이다. 첫번째 파라미터는 원본 파일 경로명이고 두번째 파라미터는 새롭게 만들어지는 타깃 경로명이다.
/dirB에 name2라는 심볼릭 링크를 만들었기 떄문에 이번에는 심볼릭 링크라는 별도의 파일이 생성이된다.그래서 inode가 별도로 생성이 된다. 그래서 이 파일안에 원본파일의 경로가 들어가있다. 그래서 /dirB/name2라는 파일을 오픈을 하겠다라고 OS에게 알려주면 OS가 탐색을 하고 이파일이 심볼릭 링크라는 것을 알기 떄문에 탐색을 멈추는 것이 아니라 이 안에 원본파일을 보고 경로를 계속 탐색을 한다. 그래서 /dirA/name1의 inode를 오픈을 해준다. 심볼릭링크 파일과 원본파일은 서로 별개라 간접적으로 연결이 되있다. 마찬가지로 name2파일을 열어서 변경을하게 되면 name2로부터 연결된 name1파일이 변경이 된다. 그래서 심볼릭으로 하나 하드링크로 하나 결국에는 같은 원본파일을 access하는거다. 간접적이나 직접적이냐라는 차이만 있을 뿐.

씸볼릭과 하드의 차이점은 삭제할떄 생긴다. temp.c라는 원본파일을 삭제를 한다면 심볼릭 링크인 경우에 심볼릭링크가 가리키는 원본파일이 삭제가 된다. temp-sym.c안에는 원본파일의 경로명이 들어가 있었는데 그 파일이 삭제가 되어서 색이 바뀌고 댐블링 포인트가 되어버렸다. 그러나 하드링크였던 temp2.c는 여전히 원본이였던 temp.c inode를가리키고 있다. temp.c는 삭제가 됐지만 temp.c의 inode는 삭제가 되지 않고 카운트 값만 하나 감소되었다. 즉 temp2.c를 이용해서 원본파일을 access할 수 있다. 그러나 심볼릭 파일을 열면 아무런 내용도 안 뜬다. 

재밌는 사실로 여기서 아까 삭제한 원본파일과 같은 이름의 파일을 다시 만든다면 이제 temp.c와 temp.2는 아예 다른 파일이 된다. 하지만 temp.c와 temp-sym.c는 다시 연결이 되었다. 그래서 temp-sym.c는 새로 만든 temp.c를 가리키는 씸볼릭 링크가 된 것이고 temp2.c는 예전파일을 가리키는 파일로 남아있게 된 것이다. 

'Computer Science > 시스템 프로그래밍' 카테고리의 다른 글

[시스템 프로그래밍] Chapter 8  (0) 2024.05.09
[시스템 프로그래밍] Chapter 6  (0) 2024.05.09
[시스템 프로그래밍] Chapter 4  (0) 2024.04.12
[시스템 프로그래밍] Chapter 3  (0) 2024.04.10
[시스템 프로그래밍] Chapter 2  (0) 2024.04.06
'Computer Science/시스템 프로그래밍' 카테고리의 다른 글
  • [시스템 프로그래밍] Chapter 8
  • [시스템 프로그래밍] Chapter 6
  • [시스템 프로그래밍] Chapter 4
  • [시스템 프로그래밍] Chapter 3
seungwon9201
seungwon9201
AI & Security
  • seungwon9201
    yyyyss
    seungwon9201
  • 전체
    오늘
    어제
    • 전체 글 (93)
      • Computer Science (37)
        • 분산시스템 (7)
        • 시스템 프로그래밍 (12)
        • 데이터 통신 (12)
        • 데이터 사이언스 (2)
        • 암호학 (4)
      • Web Hacking (16)
        • SQL (3)
        • Brute Force (1)
        • Command (1)
        • XSS (3)
        • File (2)
        • 기타 (4)
        • XXE (1)
        • 침투 테스트 (1)
      • wargame (12)
        • bandit (8)
        • dreamhack (4)
      • 리눅스 서버 보안 (18)
        • 리눅스 보안 기초 (4)
        • 안전한 웹 서버 구축 (4)
        • 데이터베이스 보안 (3)
        • 원격 접속 보안 (1)
        • FTP 보안 (1)
        • 파일 공유 서버 (2)
        • 메일 서버 (3)
      • 안드로이드 모의해킹 (10)
        • 안드로이드 이론 (3)
        • 정적 분석 (2)
        • 동적 분석 (5)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • 깃허브
  • 인기 글

  • 태그

    bandit26
    dovecot
    MariaDB
    sql injection
    개게지향 언어
    프리다
    정적 분석
    후킹
    samba
    스팸 메일 방지
    amavis
    simple tcp socket tester
    bandit21
    파일 공유 서버
    reverse shell
    메일 서버
    metasploit
    tcp 스니핑
    learnfrida
    bandit16
    androidmanifest.xm
    데이터베이스 보안
    bandit11
    tcp server
    bandit31
    sqlmap
    XSS
    방화벽
    코드 패치
    Directory Listing
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
seungwon9201
[시스템 프로그래밍] Chapter 5
상단으로

티스토리툴바