User Program이 파일 시스템, 메모리, 프린터 등의 여러 프로세스가 동시에 사용하는
자원에 접근할때, 커널 모드로 진입하기 위해 호출하는 함수.

그림으로 그리면 위와 같다.
여러 프로세스가 동시에 사용하는 자원, 즉 공유자원에 아무렇게나 접근하면
그 자원을 쓰는 모든 프로세스가 꼬일 것이기에, 커널 모드에서 이러한 자원을 제어하고,
충돌이나 데이터 손상을 방지하는 역할을 하게 된다.
Gitbook에 있는 여러 시스템 콜을 요구사항에 맞게 수정하는 것.
1. File Descriptor 관련 시스템콜
2. Deny Write on Executables 관련 시스템콜 (exec, fork, wait)
사실 2번은 제대로 이해하지 못해서 이번 글에서는 1번만 다룰 예정이다.

우리가 open_normal 이라는 테스트 코드
/* Open a file. */
#include <syscall.h>
#include "tests/lib.h"
#include "tests/main.h"
void
test_main (void)
{
int handle = open ("sample.txt");
if (handle < 2)
fail ("open() returned %d", handle);
}
를 실행할때 저기 open("sample.txt")가 Syscall.c의 open인 것 같지만
사실은 아니고 그림과 같은 flow를 따라 실행 된다.
open함수의 요구사항은 아래와 같다.
open()int open(const char *file) 로 프로토타입이 주어진다.
우리가 파일관련해서 알고 있는 것은 file descriptor table이라는 Array와 file 구조체의 구조이다.
그런데 인자로 주어지는 것이 file 이다,
그럼 우린 file이 가진 fd 번호를 찾아야 한다.
그 후에 그 fd를 리턴 해주면 된다.
따라서 첫번째로 일단 파일을 Open 하고,
두번째로 열린 그 file을 가지고 fd를 알아내는 로직만 구현하면
Open 시스템 콜 함수를 구현할 수 있다.
이 수많은 코드 중에 잘 찾아보니
/* Opens the file with the given NAME.
* Returns the new file if successful or a null pointer
* otherwise.
* Fails if no file named NAME exists,
* or if an internal memory allocation fails. */
struct file *
filesys_open (const char *name) {
struct dir *dir = dir_open_root ();
struct inode *inode = NULL;
if (dir != NULL)
dir_lookup (dir, name, &inode);
dir_close (dir);
return file_open (inode);
}
요런 함수가 있었다.
주석을 보면 주어진 이름의 파일을 디렉토리에서 찾아서 열어주는 함수가 있었다.
이걸 통해서 Parameter로 주어진 파일을 Open하는 첫번째 logic을 쉽게 구현할 수 있다.
if (!check_addr(file))
{
exit(-1);
}
lock_acquire(&filesys_lock);
struct file *file_1 = filesys_open(file);
lock_release(&filesys_lock);
struct thread *curr = thread_current();
열기전에 커널 영역을 침범하는지 확인 후
파일 시스템 역시 공유자원이기에 Lock을 활용하여 공유자원 접근을 막았다.
이후 위에서 서술한 함수를 활용하여 파일을 열었다.
// int64_t fd;
struct file *fdt[64];
본인은 이중포인터 개념이 이해가 안되어서 배열로 직접 만들었다.
따라서 직접 하나씩 반복문으로 돌면서 빈 fd 자리를 찾아가야 했다.
for (int i = 2; i < 64; i++)
{
if (curr->fdt[i] == NULL)
{
// 넣어주고
curr->fdt[i] = file_1;
return i;
}
}
현재 스레드의 fdt에서 빈 자리(NULL)을 만날때까지 돌면서
만약 빈자리를 찾는다면 그 자리가 file이 들어갈 fd 기때문에 바로 리턴해준다.
open 함수는 이렇게 끝이다.
int open(const char *file)
{
if (!check_addr(file))
{
exit(-1);
}
lock_acquire(&filesys_lock);
struct file *file_1 = filesys_open(file);
lock_release(&filesys_lock);
struct thread *curr = thread_current();
if (file_1 == NULL)
{
return -1;
}
else
{
for (int i = 2; i < 64; i++)
{
if (curr->fdt[i] == NULL)
{
// 넣어주고
curr->fdt[i] = file_1;
return i;
}
}
}
}
2주라는 시간 동안 시스템 콜을 직접 구현해보면서
공유자원이라는 개념, 커널모드와 사용자 모드라는 개념에 대해 더 명확히 알 수 있었다.