pass tests/userprog/open-normal
pass tests/userprog/open-missing
pass tests/userprog/open-boundary
pass tests/userprog/open-empty
pass tests/userprog/open-null
pass tests/userprog/open-bad-ptr
pass tests/userprog/open-twice
int sys_open(const char *file);
open()μ νΈμΆνμ λ-1 λ°νthreads/thread.hthreads/thread.cuserprog/syscall.cuserprog/syscall.hνμΌ: threads/thread.h
#define FD_MAX 128 // μ΄λ¦° νμΌμ μ΅λ μ
struct thread {
...
struct file *fd_table[FD_MAX]; // μ΄λ¦° νμΌ ν
μ΄λΈ
int next_fd; // λ€μμΌλ‘ ν λΉν fd
...
};
νμΌ: threads/thread.c
ν¨μ: init_thread(struct thread *t, ...)
t->next_fd = 2;
for (int i = 0; i < FD_MAX; i++)
t->fd_table[i] = NULL;
νμΌ: userprog/syscall.c
int sys_open(const char *file) {
if (file == NULL || !is_user_vaddr(file) || pml4_get_page(thread_current()->pml4, file) == NULL)
sys_exit(-1); // ν¬μΈν° μ ν¨μ± κ²μ¬
lock_acquire(&file_lock); // λ½ νλ
struct file *f = filesys_open(file); // νμΌ μ΄κΈ°
lock_release(&file_lock); // λ½ ν΄μ
if (f == NULL)
return -1; // νμΌ μμΌλ©΄ μ€ν¨
struct thread *cur = thread_current();
int fd = cur->next_fd;
while (fd < FD_MAX && cur->fd_table[fd] != NULL)
fd++; // λΉμ΄ μλ fd μ°ΎκΈ°
if (fd >= FD_MAX)
return -1; // μ΄ μ μλ νμΌ μ΄κ³Ό
cur->fd_table[fd] = f;
cur->next_fd = fd + 1;
return fd; // fd λ°ν
}
νμΌ: userprog/syscall.c
case SYS_OPEN:
f->R.rax = sys_open((const char *)f->R.rdi);
break;
νμΌ: userprog/syscall.h
int sys_open(const char *file);
ν΄λΉ ꡬνμ ν΅ν΄ μλ ν μ€νΈλ₯Ό ν΅κ³Όνμλ€.
νμΌ μ΄λ¦ μ ν¨μ±, ν¬μΈν° κ²μ¬, μ€λ³΅ μ€ν μ²λ¦¬ λ± λ€μν κ²½μ°λ₯Ό λ€λ£¨κ³ μμΌλ©°
fd_tableκ³Ό next_fdμ μ¬λ°λ₯Έ μ€κ³μ μμΈ μ²λ¦¬κ° μ€μνλ€.
open μμ€ν
μ½μ ꡬννλ©΄μ μ μ ν¬μΈν° κ²μ¦, λ½ λκΈ°ν,
νμΌ λμ€ν¬λ¦½ν° ν
μ΄λΈ μ€κ³λΌλ μ€μν ꡬ쑰λ€μ μ΄ν΄ν μ μμλ€.
μ΄λ μ΄ν read, write, fork ꡬνμ κΈ°λ°μ΄ λλ ν΅μ¬ μμμ΄λ€.
μ΄μ close μμ€ν
μ½ κ΅¬νμΌλ‘ λμ΄κ° μ μλ€.