File descriptor
- File descriptor
- UNIX의 I/O 함수를 사용할 때 file descriptor를 사용한다.
- open, read, write, close, ioctl
- STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO(unistd.h)

File descriptor table
- 호출한 process마다 가지고 있는 file descriptor table은 오픈된 파일의 각각에 접근할 수 있는 entry로 차있다.
- 기본적으로 프로세스가 생성이 되면 file descriptor table의 위 3개는 기본적으로 차있게 되는데, 표준 I/O(stdin, stdout, stderr)가 들어가게 된다.
- open함수가 실행되면 table에 이미 차있는 0,1,2의 다음인 3번에 entry가 추가된다.
- 그러므로 file descriptor는 File descriptor table의 index값을 말한다.
- 새로 들어온 entry는 System file table로 가는 entry 정보를 가진다.
System file table
- 모든 파일에서 공유되는 table이다.
- inode table로 가는 entry 정보를 가진다.
- open함수가 실행되면 File descriptor table과 마찬가지로 System file table에도 정보가 들어온다.
- 정보는 file offset, access mode, 참조하고 있는 file descriptor table의 개수인 Count 정보가 있다.
In-memory inode table
- open함수가 실행되면 inode table에도 entry가 추가된다.
- 저장되어 있는 원래 파일(inode)에 대한 위치 정보를 가진다.
- 참조하고 있는 System file table의 개수인 Count라는 정보를 가지고 있다.
정리
File descriptor = File descriptor table의 index
File descriptor table의 정해진 index
-> 를 통해 읽은 System file table의 entry
-> 를 통해 읽은 inode table의 실제 파일에 대한 위치 정보
-> 를 통해 읽은 실제 파일을 열기
여러가지 질문
- close함수를 실행하여 file descriptor를 닫으면 무슨 일이 일어나는가?
- 먼저 File descriptor table의 index를 삭제한다.
- 참조하고 있는 System file table안의 entry의 Count값을 하나 감소시킨다.
- 만약 Count값이 0이 되면 자신을 삭제한다. 그 후 inode table의 entry의 Count값을 하나 감소시킨다.
- 만약 Count값이 0이 되면 자신을 삭제한다.
- 두 프로세스가 똑같은 파일을 write하면 무슨 일이 일어나는가?
- 각각의 process는 서로 다른 file offset을 가지고 있다. 파일을 write한다는 의미는 file offset을 기준으로 작성하므로 덮어쓰게 될 것이다.
- 만약 file offest이 inode table값 안에 있다면 어떻게 되는가?
- 두개의 프로세스가 동일한 file offest을 공유하게 되므로 파일을 이어쓰게 될 것이다.
File pointer
- C라이브러리의 함수를 사용할 때 File pointer를 사용한다.
- fopen, fscanf, fprintf, fread, fwrite, fclose
- stdin, stdout, stderr(stdio.h)
- 파일은 임시로 저장이 되는 공간인 buffer를 가지고 있다. 이 buffer공간은 file pointer를 사용할 때 불러진다. file pointer를 사용하면 바로 파일에 함수가 적용되는 것이 아니라 먼저 buffer공간에 저장된다. 그 후 조건이 만족되면 실제 파일에서 수행된다.
- fprintf();
- 실제 디스크에 적히는게 아니라 buffer안에 먼저 적히게 된다.
- 버퍼가 가득 차면 I/O 시스템은 file descriptor와 함께 파일에 write된다.
- 버퍼가 가득 찬다는 점 때문에 buffering delay를 피하기 위해서 fflush라는 함수가 있다. fflush는 버퍼를 강제로 비우는 함수이다.
- 터미널 파일은 fully buffered되지 않고 line buffered된다. 다시 말해 라인 단위로 버퍼링 된다는 소리다. 왜냐하면 우선순위가 높기 때문에 다 기다릴 필요 없이 빠르게 내보낸다.
