
2025.05.26
thread.h
------------------------------
#define MAX_FD 128
struct thread {
…
struct file *fd_table[MAX_FD]; /* 프로세스별 열린 파일 포인터 */
int next_fd; /* 다음 할당할 FD 번호 */
};
thread.c
------------------------------
static void init_thread(struct thread *t, …) {
…
for (int i = 0; i < MAX_FD; i++)
t->fd_table[i] = NULL;
t->next_fd = 2; /* 0: stdin, 1: stdout 예약 */
…
}
__do_fork()
-------------------------------
for (int fd = 2; fd < MAX_FD; fd++)
{
struct file *f = parent->fd_table[fd];
if (f != NULL)
current->fd_table[fd] = file_duplicate(f);
}
current->next_fd = parent->next_fd;
// fd_table 순회하여 file_close()
for (int fd = 2; fd < MAX_FD; fd++)
{
if (curr->fd_table[fd])
{
file_close(curr->fd_table[fd]);
curr->fd_table[fd] = NULL;
}
}
file 이름의 파일을 열고, 성공하면 새 파일 디스크립터(fd)를 반환. 실패하면 –1 반환.open(file) 호출 → 레지스터에 SYS_OPEN과 file 포인터를 담고 syscall 실행check_user_address() / check_user_buffer()로 file 문자열 검사filesys_open(file) → struct file* 얻음allocate_fd(fptr) → thread_current()->fd_table[fd] = fptrfile_close(fptr) 후 –1, 성공 시 fd 반환fd로부터 최대 size 바이트를 buffer에 읽어서 실제 읽은 바이트 수를 반환. stdin(fd=0)은 키보드 입력. 오류 시 –1.read(fd, buffer, size) 호출 → 레지스터에 SYS_READ, fd, buffer, size 담고 syscall 실행sys_read() 구현check_user_address() / check_user_buffer()로 buffer 검사fd==0 → input_getc() 반복 호출fd>1 → file_read(fd_table[fd], buffer, size)fd에 buffer의 내용을 size 바이트만큼 기록하고, 성공하면 기록한 바이트 수 반환. stdout(fd=1)은 콘솔 출력. 오류 시 –1.write(fd, buffer, size) 호출 → 레지스터에 SYS_WRITE, fd, buffer, size 담고 syscall 실행sys_write() 구현check_user_address() / check_user_buffer()로 buffer 검사fd==1 → putbuf(buffer, size) (콘솔)fd>1 → file_write(fd_table[fd], buffer, size)fd가 가리키는 파일을 닫고, 해당 엔트리를 해제(free_fd).close(fd) 호출 → 레지스터에 SYS_CLOSE, fd 담고 syscall 실행fd (>1 && < MAX_FD)인지 검사file_close(fd_table[fd]), free_fd(fd)file을 크기 initial_size로 생성. 성공 시 true, 실패 시 false.create(file, size) 호출 → 레지스터에 SYS_CREATE, file, size 담고 syscall 실행check_user_address() / check_user_buffer()로 file 검사filesys_create(file, initial_size) 호출file을 삭제. 성공 시 true, 실패 시 false.remove(file) 호출 → 레지스터에 SYS_REMOVE, file 담고 syscall 실행check_user_address() / check_user_buffer()로 file 검사filesys_remove(file) 호출fd가 가리키는 파일의 크기를 바이트 단위로 반환. 오류 시 –1.filesize(fd) 호출 → 레지스터에 SYS_FILESIZE, fd 담고 syscall 실행fd인지 검사file_length(fd_table[fd]) 호출 후 반환fd의 읽기/쓰기 위치(offset)를 position으로 설정.seek(fd, pos) 호출 → 레지스터에 SYS_SEEK, fd, position 담고 syscall 실행fd인지 검사file_seek(fd_table[fd], position) 호출fd의 현재 읽기/쓰기 위치(offset)를 반환. 오류 시 0.tell(fd) 호출 → 레지스터에 SYS_TELL, fd 담고 syscall 실행fd인지 검사file_tell(fd_table[fd]) 호출 후 반환inode.c
----------------------
struct inode {
struct list_elem elem;
disk_sector_t sector;
int open_cnt;
bool removed;
int deny_write_cnt;
struct inode_disk data;
struct lock inode_lock; /* ← 여기 추가 */
};
struct inode *inode_open(disk_sector_t sector){}
/* inode가 새로 생성되었으니 락도 초기화 */
lock_init(&inode->inode_lock);
inode_read_at(), inode_write_at(), inode_deny_write(), inode_allow_write(), inode_remove() , innode_reopen()에 락 설정lock_acquire(&inode->inode_lock);
…;
lock_release(&inode->inode_lock);