[PintOS Project 2] TIL - 7

옵주비·2022년 6월 5일
0

PintOS Project2

목록 보기
7/9
post-thumbnail

(6/3)
지난 번에 예고한대로, 오늘은 file descriptor 관련한 시스템 콜에 대해 정리해보겠다. 원래는 Extra 과제를 하기 전에 이걸 먼저 정리하려고 했는데, 목요일 저녁~금요일 오전에 걸쳐 슬쩍 읽어두었던 Extra 과제 관련 깃북 내용이 잘 이해되어서 그냥 구현 자체를 다 끝내버리고, 차례대로 정리 중이다.

그럼 fd 관련 시스템 콜을 차례대로 정리해보자!


fd 관련 보조 함수 구현

각종 fd 관련 시스템 콜을 구현하기에 앞서, 편의를 위해 다음의 함수를 구현해주었다. 파일 디스크립터(fd) 처리가 여러 시스템 콜 내에서 이루어지기에, 함수로 따로 빼서 구현하면 중복되는 내용을 보다 손쉽게 처리할 수 있기 때문이다.

process_get_file()

어떤 파일 디스크립터(fd)가 유효한지, 즉 현재 실행중인 쓰레드의 파일 디스크립터 테이블(fd_table)의 fd에 NULL이 아니라 무언가가 들어있는지 확인해주는 함수가 필요한데, 그게 바로 process_get_file 이다. 구현은 간단히 아래와 같이 해주었다.

process_add_file()

어떤 파일 구조체(f)가 주어졌을 때, 현재 쓰레드의 fd_table에 빈 공간이 있는 경우, 거기에 f를 추가해주는 함수이다. 만약 빈 공간이 없으면, -1을 리턴해 에러처리를 해준다.

process_close_file()

현재 실행중인 쓰레드의 fd_table에서 주어진 파일 디스크립터(fd)를 NULL로 변경해 닫아주는 함수이다. 만약 fd가 유효범위 내에 있지 않으면, 아무 동작도 하지 않고 NULL을 리턴해 종료하도록 구현해주었다.


fd 관련 시스템 콜

OPEN

open은 문자열로 주어진 파일명 file 에 해당하는 파일을 열어주는 함수이다.

open 시스템 콜이 성공적으로 fd를 반환하기 위해서는, filesys_open 함수와 process_add_file 함수 두 가지를 무사히 통과해야 한다. 만약 파일 열기 자체에 실패하면, -1을 바로 리턴해준다. 또한, process_add_file을 호출했는데 fd_table에 빈 공간이 없는 경우에도 -1을 리턴하게 된다.

참고로 깃북에서 fd번호 0과 1은 이미 console을 위해 STDIN, STDOUT 용도로 예약된 번호임을 유의해야 한다고 하는데, 이는 process_add_file 에서 처리해주게 된다.

위의 요구사항을 반영해 구현한 open 함수는 다음과 같다.

FILESIZE

filesizefd 의 크기를 byte 단위로 반환해주는 함수다.

filesize 시스템 콜은 인자로 fd를 받아서, 현재 실행중인 쓰레드의 fd_table에 열어준 파일이 있는지 우선 확인한다. 존재하는 경우에는 그 파일의 크기를 byte 단위로 리턴해주게 된다. 구현은 간단히 아래와 같이 해주었다.

READ

read는, fd 에서 size 바이트만큼 읽어서 buffer에 저장해주는 함수다.

만약 fd가 STDIN에 해당하는 경우엔 input_getc()를 통해 최대 size만큼의 바이트를 읽어주고, 실제로 읽어들이는데 성공한 크기를 readsize로 리턴해준다. fd가 일반 파일에 해당하는 경우엔, filesys_lock 을 활용해 파일을 안전하게 읽어들이도록 한다.

struct lock filesys_lock;

참고로 해당 lock은 syscall.h 내에 간단히 선언해주었다. fd가 유효한 파일이면, read는 이 filesys_lock을 획득해 파일을 안전하게 읽어들이고, 다 읽으면 락을 해제해준다. 구현해 준 코드는 다음과 같다.

WRITE

writebuffer 에서 size바이트 만큼 읽어서 fd 파일에 써주는 함수이다.

write는 read와 구조가 거의 비슷하다. 만약 fd가 STDOUT에 해당하는 경우엔 putbuf()를 통해 size 바이트만큼을 한번에 읽어들여 출력해주고, 크기를 writesize로 리턴해준다. 반면 fd가 일반 파일에 해당하는 경우엔, filesys_lock 을 활용해 파일에 안전하게 작성해주도록 한다.

SEEK

seekfd에서 read하거나 write할 다음 위치를, position으로 변경해주는 함수이다.

seek 시스템 콜은 이미 존재하는 함수인 file_seek을 호출해서 구현해주었다. 한 줄 짜리라서 그냥 직접 써줘도 되긴 하지만, 이미 있는 함수를 굳이 쓰지 않을 필요는 없어보여서 큰 고민없이 적용해주었다.

TELL

tell은, seek에서 조정해주는 fd의 pos를 그대로 가져오는 함수이다.

역시나, 이미 존재하는 file_tell 함수를 활용해 손쉽게 구현해주었다.

CLOSE

closefd에 해당하는 파일과 파일 디스크립터를 닫아주는 함수이다.

fd에 해당하는 파일을 현재 실행중인 쓰레드의 fd_table에서는 NULL로 바꿔 제거해주고, file_close 함수를 호출해 해당 파일 자체를 닫아주도록 구현해주었다.

file_close 함수에서는 아래와 같이 파일 자체를 닫아주고, 해당 공간을 free해준다.

현재로써는 close 시스템 콜을 통해서 STDIN, STDOUT에 대한 fd는 닫지 못하도록 해주었는데, 이에 대한 개선은 추후에 extra 과제에서 다루게 될 것이다!

마무리

이렇게 해서 fd에 관련된 시스템 콜까지, extra 과제 이전의 대부분에 대한 정리를 마무리했다! 남은 extra 과제까지 꼭 정리해봐야겠다:) 확실히 하루하루 TIL을 쓰니까, 정리도 잘 되고 부족한 부분도 쉽게 파악이 되는 것 같다! 앞으로도 꾸준히 써야지..

0개의 댓글