From 366b1a94afe362f71b348d01ed8940765413ea41 Mon Sep 17 00:00:00 2001 From: chwangmin Date: Sat, 10 Jun 2023 14:47:15 +0000 Subject: [PATCH] :sparkles: Add : SystemCall All Pass #15 --- .gitignore | 61 +++++++++ include/threads/loader.h | 2 +- include/threads/thread.h | 26 ++++ include/userprog/process.h | 8 +- include/userprog/syscall.h | 3 +- lib/user/entry.c | 1 + output/test | Bin 0 -> 35256 bytes threads/thread.c | 36 ++++-- userprog/exception.c | 2 +- userprog/process.c | 163 +++++++++++++++++++++--- userprog/syscall.c | 249 ++++++++++++++++++++++++++++++++++++- 11 files changed, 524 insertions(+), 27 deletions(-) create mode 100644 .gitignore create mode 100755 output/test diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2593bb6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,61 @@ +# Created by https://www.toptal.com/developers/gitignore/api/c +# Edit at https://www.toptal.com/developers/gitignore?templates=c + +### C ### +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf + +# git_ignore +*.bin + +# End of https://www.toptal.com/developers/gitignore/api/c \ No newline at end of file diff --git a/include/threads/loader.h b/include/threads/loader.h index 9dfee6f..b063e73 100644 --- a/include/threads/loader.h +++ b/include/threads/loader.h @@ -5,7 +5,7 @@ #define LOADER_BASE 0x7c00 /* Physical address of loader's base. */ #define LOADER_END 0x7e00 /* Physical address of end of loader. */ -/* Physical address of kernel base. */ +/* Virtual address of kernel base. */ #define LOADER_KERN_BASE 0x8004000000 /* Kernel virtual address at which all physical memory is mapped. */ diff --git a/include/threads/thread.h b/include/threads/thread.h index aecd4c4..ccd29ee 100644 --- a/include/threads/thread.h +++ b/include/threads/thread.h @@ -5,6 +5,7 @@ #include #include #include "threads/interrupt.h" +#include "threads/synch.h" // 이것을 추가해야 포인터를 쓸 수 있습니다. #ifdef VM #include "vm/vm.h" #endif @@ -28,6 +29,9 @@ typedef int tid_t; #define PRI_DEFAULT 31 /* Default priority. */ #define PRI_MAX 63 /* Highest priority. */ +#define FDT_PAGES 2 +#define FDT_COUNT_LIMIT 128 + /* A kernel thread or user process. * * Each thread structure is stored in its own 4 kB page. The @@ -94,12 +98,28 @@ struct thread { int64_t wakeup_tick; /* 해당 쓰레드가 깨어나야 할 tick을 저장할 필드 */ /* Shared between thread.c and synch.c. */ struct list_elem elem; /* List element. */ + /*priority donation 관련 항목 추가*/ int init_priority; /* donation 이후 우선순위를 초기화하기 위해 초기값 저장 */ struct lock *wait_on_lock; /* 해당 스레드가 대기 하고 있는 lock자료구조의 주소를 저장 */ struct list donations; /* multiple donation 을 고려하기 위해 사용 */ struct list_elem donation_elem; /* multiple donation 을 고려하기 위해 사용 */ + /*project 2 - SystemCall 항목 추가*/ + int exit_status; /* exit 호출 시 종료 status */ + struct file **fdt; /* 부모 프로세스의 디스크립터 */ + int next_fd; /* 다음 디스크립트를 가리키는 테이블 번호 */ + + struct intr_frame parent_if; /* 프로세스 프로그램 메모리 적재 */ + struct list child_list; /* 자식 리스트 */ + struct list_elem child_elem; /* 자식 리스트 element */ + + struct semaphore load_sema; /* load 세마포어 */ + struct semaphore exit_sema; /* exit 세마포어 */ + struct semaphore wait_sema; /* wait 세마포어 */ + + struct file *running; // 현재 실행중인 파일 + #ifdef USERPROG /* Owned by userprog/process.c. */ uint64_t *pml4; /* Page map level 4 */ @@ -155,6 +175,10 @@ int64_t get_next_tick_to_awake(void); void test_max_priority(void); bool cmp_priority(const struct list_elem *a, const struct list_elem *b, void *aux UNUSED); +// project2 +bool cmp_thread_priority(const struct list_elem *a, const struct list_elem *b, void *aux); +bool cmp_thread_ticks(const struct list_elem *a, const struct list_elem *b, void *aux); +// --- void donate_priority(void); void remove_with_lock(struct lock *lock); @@ -163,4 +187,6 @@ void refresh_priority(void); bool thread_compare_donate_priority(const struct list_elem *x, const struct list_elem *y, void *aux UNUSED); +void preempt_priority(void); + #endif /* threads/thread.h */ diff --git a/include/userprog/process.h b/include/userprog/process.h index 4365424..43a9d3b 100644 --- a/include/userprog/process.h +++ b/include/userprog/process.h @@ -9,5 +9,11 @@ int process_exec (void *f_name); int process_wait (tid_t); void process_exit (void); void process_activate (struct thread *next); - +/* project 2 */ +void argument_stack(char **argv, int argc, void **rsp); +struct thread *get_child_process(int pid); +int process_add_file(struct file *f); +struct file *process_get_file(int fd); +void process_close_file(int fd); +struct thread *get_child_process(int pid); #endif /* userprog/process.h */ diff --git a/include/userprog/syscall.h b/include/userprog/syscall.h index 9059096..7b281ba 100644 --- a/include/userprog/syscall.h +++ b/include/userprog/syscall.h @@ -2,5 +2,6 @@ #define USERPROG_SYSCALL_H void syscall_init (void); +struct lock filesys_lock; -#endif /* userprog/syscall.h */ +#endif /* userprog/syscall.h */ \ No newline at end of file diff --git a/lib/user/entry.c b/lib/user/entry.c index 46f2d59..d324fdc 100644 --- a/lib/user/entry.c +++ b/lib/user/entry.c @@ -3,6 +3,7 @@ int main (int, char *[]); void _start (int argc, char *argv[]); +// user program의 진입점이다. void _start (int argc, char *argv[]) { exit (main (argc, argv)); diff --git a/output/test b/output/test new file mode 100755 index 0000000000000000000000000000000000000000..04181158bbff9e8394f1c911b3d4b7d569fa1832 GIT binary patch literal 35256 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.cs = SEL_KCSEG; t->tf.eflags = FLAG_IF; + /* 현재 스레드의 자식으로 추가 */ + list_push_back(&thread_current()->child_list, &t->child_elem); + + /* File Descriptor 테이블 메모리 할당 */ + t->fdt = palloc_get_multiple(PAL_ZERO, FDT_PAGES); + if (t->fdt == NULL) // 메모리 할당 실패시 에러 리턴. + return TID_ERROR; // -1 + /* Add to run queue. */ thread_unblock(t); + preempt_priority(); + + return tid; +} - /* 현재 실행중인 thread와 우선순위를 비교하여, 새로 생성된 - thread의 우선순위가 높다면 thread_yield()를 통해 CPU를 양보 */ +/* 현재 실행중인 thread와 우선순위를 비교하여, 새로 생성된 +thread의 우선순위가 높다면 thread_yield()를 통해 CPU를 양보 */ +void preempt_priority(void) +{ + if (thread_current() == idle_thread) + return; + if (list_empty(&ready_list)) + return; struct thread *curr = thread_current(); - if (t->priority > curr->priority) - { + struct thread *ready = list_entry(list_front(&ready_list), struct thread, elem); + if (curr->priority < ready->priority) // ready_list에 현재 실행중인 스레드보다 우선순위가 높은 스레드가 있으면 thread_yield(); - } - - return tid; } /* Puts the current thread to sleep. It will not be scheduled @@ -441,6 +456,13 @@ init_thread(struct thread *t, const char *name, int priority) t->init_priority = priority; // 초기 중요도 값 설정 t->wait_on_lock = NULL; // 기다리는 락은 NULL로 설정 list_init(&t->donations); // 스레드의 donations를 초기화 + + t->exit_status = 0; /* exit status 는 0으로 초기화 */ + t->next_fd = 2; /* next_fd 는 2로 초기화 (0 - 표준 입력, 1 - 표춘출력) */ + sema_init(&t->load_sema, 0); /* load의 세마 초기화 */ + sema_init(&t->exit_sema, 0); /* exit의 세마 초기화 */ + sema_init(&t->wait_sema, 0); /* wait의 세마 초기화 */ + list_init(&(t->child_list)); /* child_list를 초기화(head,tail 지정) */ } /* Chooses and returns the next thread to be scheduled. Should diff --git a/userprog/exception.c b/userprog/exception.c index bf4a9b2..7a06673 100644 --- a/userprog/exception.c +++ b/userprog/exception.c @@ -134,11 +134,11 @@ page_fault (struct intr_frame *f) { be assured of reading CR2 before it changed). */ intr_enable (); - /* Determine cause. */ not_present = (f->error_code & PF_P) == 0; write = (f->error_code & PF_W) != 0; user = (f->error_code & PF_U) != 0; + exit(-1); #ifdef VM /* For project 3 and later. */ diff --git a/userprog/process.c b/userprog/process.c index a186a09..d7c0e59 100644 --- a/userprog/process.c +++ b/userprog/process.c @@ -50,6 +50,8 @@ process_create_initd (const char *file_name) { return TID_ERROR; strlcpy (fn_copy, file_name, PGSIZE); + char *save_ptr; // 분리된 문자열 중 남는 부분의 시작주소 + strtok_r(file_name, " ", &save_ptr); /* Create a new thread to execute FILE_NAME. */ tid = thread_create (file_name, PRI_DEFAULT, initd, fn_copy); if (tid == TID_ERROR) @@ -74,10 +76,39 @@ initd (void *f_name) { /* Clones the current process as `name`. Returns the new process's thread id, or * TID_ERROR if the thread cannot be created. */ tid_t -process_fork (const char *name, struct intr_frame *if_ UNUSED) { +process_fork (const char *name, struct intr_frame *if_ UNUSED) +{ /* Clone current thread to new thread.*/ - return thread_create (name, - PRI_DEFAULT, __do_fork, thread_current ()); + // 현재 스레드의 parent_if에 복제해야 하는 if를 복사한다. + struct thread *cur = thread_current(); + memcpy(&cur->parent_if, if_, sizeof(struct intr_frame)); + + // 현재 스레드를 fork한 new 스레드를 생성한다. + tid_t pid = thread_create(name, PRI_DEFAULT, __do_fork, cur); + if (pid == TID_ERROR) + return TID_ERROR; + + // 자식이 로드될 때까지 대기하기 위해서 방금 생성한 자식 스레드를 찾는다. + struct thread *child = get_child_process(pid); + + // 현재 스레드는 생성만 완료된 상태이다. 생성되어서 ready_list에 들어가고 실행될 때 __do_fork 함수가 실행된다. + // __do_fork 함수가 실행되어 로드가 완료될 때까지 부모는 대기한다. + sema_down(&child->load_sema); + + // 자식이 로드되다가 오류로 exit한 경우 + if (child->exit_status == -2) + { + // 자식이 종료되었으므로 자식 리스트에서 제거한다. + // 이거 넣으면 간헐적으로 실패함 (syn-read) + // list_remove(&child->child_elem); + // 자식이 완전히 종료되고 스케줄링이 이어질 수 있도록 자식에게 signal을 보낸다. + sema_up(&child->exit_sema); + // 자식 프로세스의 pid가 아닌 TID_ERROR를 반환한다. + return TID_ERROR; + } + + // 자식 프로세스의 pid를 반환한다. + return pid; } #ifndef VM @@ -91,22 +122,34 @@ duplicate_pte (uint64_t *pte, void *va, void *aux) { void *newpage; bool writable; + //모름 /* 1. TODO: If the parent_page is kernel page, then return immediately. */ + if (is_kernel_vaddr(va)) + return true; /* 2. Resolve VA from the parent's page map level 4. */ - parent_page = pml4_get_page (parent->pml4, va); + parent_page = pml4_get_page(parent->pml4, va); + if (parent_page == NULL) + return false; + /* 3. TODO: Allocate new PAL_USER page for the child and set result to * TODO: NEWPAGE. */ + newpage = palloc_get_page(PAL_USER | PAL_ZERO); + if (newpage == NULL) + return false; /* 4. TODO: Duplicate parent's page to the new page and * TODO: check whether parent's page is writable or not (set WRITABLE * TODO: according to the result). */ + memcpy(newpage, parent_page, PGSIZE); + writable = is_writable(pte); /* 5. Add new page to child's page table at address VA with WRITABLE * permission. */ if (!pml4_set_page (current->pml4, va, newpage, writable)) { /* 6. TODO: if fail to insert page, do error handling. */ + return false; } return true; } @@ -122,11 +165,12 @@ __do_fork (void *aux) { struct thread *parent = (struct thread *) aux; struct thread *current = thread_current (); /* TODO: somehow pass the parent_if. (i.e. process_fork()'s if_) */ - struct intr_frame *parent_if; + struct intr_frame *parent_if = &parent -> parent_if; // 모름 bool succ = true; /* 1. Read the cpu context to local stack. */ memcpy (&if_, parent_if, sizeof (struct intr_frame)); + if_.R.rax = 0; // 자식 프로세스의 리턴 값은 0이다. /* 2. Duplicate PT */ current->pml4 = pml4_create(); @@ -149,13 +193,27 @@ __do_fork (void *aux) { * TODO: from the fork() until this function successfully duplicates * TODO: the resources of parent.*/ + // FDT 복사 + for (int i = 0; i < FDT_COUNT_LIMIT; i++) + { + struct file *file = parent->fdt[i]; + if (file == NULL) + continue; + if (file > 2) + file = file_duplicate(file); + current->fdt[i] = file; + } + current->next_fd = parent->next_fd; + + sema_up(¤t->load_sema); process_init (); /* Finally, switch to the newly created process. */ if (succ) do_iret (&if_); error: - thread_exit (); + sema_up(¤t->load_sema); + exit(-2); } /* Switch the current execution context to the f_name. @@ -206,11 +264,11 @@ process_exec (void *f_name) { _if.R.rdi = argc; // rdi(stack의 첫번째 인자?)에 크기 저장 _if.R.rsi = (uint64_t)*rspp + sizeof(void *); // 스택에 저장된 주소들의 첫번째 주소 argv[0]의 주소 저장 - hex_dump(_if.rsp, _if.rsp, USER_STACK - (uint64_t)*rspp, true); palloc_free_page(file_name); + do_iret(&_if); + hex_dump(_if.rsp, _if.rsp, USER_STACK - (uint64_t)*rspp, true); /* Start switched process. */ - do_iret(&_if); NOT_REACHED(); } @@ -229,8 +287,17 @@ process_wait (tid_t child_tid UNUSED) { /* XXX: Hint) The pintos exit if process_wait (initd), we recommend you * XXX: to add infinite loop here before * XXX: implementing thfe process_wait. */ - for (int i=0;i<100000000;i++){} - return -1; + struct thread *child = get_child_process(child_tid); + if (child == NULL)// 자식이 아니면 -1을 반환한다. + return -1; + // 자식이 종료될 때까지 대기한다. (process_exit에서 자식이 종료될때 sema_up 해줄 것) + sema_down(&child->wait_sema); + /* 자식이 종료됨을 알리는 `wait_sema` signal을 받으면 현재 스레드(부모)의 자식 리스트에서 제거한다. */ + list_remove(&child->child_elem); + /* 자식이 완전히 종료되고 스케줄링이 이어질 수 있도록 자식에게 signal을 보낸다. */ + sema_up(&child->exit_sema); + + return child->exit_status; /* 자식의 exit_status를 반환한다. */ } /* Exit the process. This function is called by thread_exit (). */ @@ -242,7 +309,19 @@ process_exit (void) { * TODO: project2/process_termination.html). * TODO: We recommend you to implement process resource cleanup here. */ + /* 프로세스 종료가 일어날 경우 프로세스에 열려있는 모든 파일을 닫음. */ + for (int i = 2; i < FDT_COUNT_LIMIT; i++) // 프로세스에 열린 모든 파일 확인 + { + if (curr->fdt[i] != NULL) /* 현재 프로세스가 null 이 아니면 닫기. 변경요망(파일 디스크립터의 최소값인 2가 될 때까지 파일을 닫음)*/ + close(i); + } + palloc_free_multiple(curr->fdt, FDT_PAGES); /* 파일 테이블 */ + file_close(curr->running); /* 현재 실행 중인 파일도 닫는다. */ + process_cleanup (); + + sema_up(&curr->wait_sema); /* 자식이 종료될 때까지 대기하고 있는 부모에게 signal을 보낸다. */ + sema_down(&curr->exit_sema); /* 부모의 signal을 기다린다. 대기가 풀리고 나서 do_schedule(THREAD_DYING)이 이어져 다른 스레드가 실행된다. */ } /* Free the current process's resources. */ @@ -432,7 +511,10 @@ load (const char *file_name, struct intr_frame *if_) { break; } } - + // 스레드가 삭제될 때 파일을 닫을 수 있게 구조체에 파일을 저장해둔다. + t->running = file; + // 현재 실행중인 파일은 수정할 수 없게 막는다. + file_deny_write(file); /* Set up stack. */ if (!setup_stack (if_)) goto done; @@ -447,7 +529,7 @@ load (const char *file_name, struct intr_frame *if_) { done: /* We arrive here whether the load is successful or not. */ - file_close (file); + //file_close (file); return success; } @@ -704,9 +786,62 @@ void argument_stack(char **argv, int argc, void **rsp) **(char ***)rsp = argv[i]; // argv[i]의 주소값을 저장 } - // Return address - printf("\n abcd~~ abcd~~~ 0x%02X \n", *(uint16_t **)rsp); (*rsp) -= 8; // 마지막 값을 // 마지막 fake address 값을 넣어준다. **(void ***)rsp = 0; // rsp의 값을 0으로 지정한다. +} + +/* 자식 리스트를 검색하여 프로세스 디스크립터의 주소 리턴 */ +struct thread *get_child_process(int pid) +{ + struct thread *cur = thread_current(); + struct list *child_list = &cur->child_list; + for (struct list_elem *e = list_begin(child_list); e != list_end(child_list); e = list_next(e)) + { + struct thread *t = list_entry(e, struct thread, child_elem); + /* 해당 pid가 존재하면 프로세스 디스크립터 반환 */ + if (t->tid == pid) + return t; + } + /* 리스트에 존재하지 않으면 NULL 리턴 */ + return NULL; +} + +// 파일 객체에 대한 파일 디스크립터를 생성하는 함수 +int process_add_file(struct file *f) +{ + struct thread *curr = thread_current(); + struct file **fdt = curr->fdt; + + // limit을 넘지 않는 범위 안에서 빈 자리 탐색 + while(curr->next_fd < FDT_COUNT_LIMIT && fdt[curr->next_fd]) + curr->next_fd++; // 파일 디스크립터의 최대값 1 증가 + if (curr->next_fd >= FDT_COUNT_LIMIT) // 파일 디스크립터가 128보다 크면 오류 삭제 + return -1; + fdt[curr->next_fd] = f; // 비어 있는 fd에 file에 대한 값 넣기. + + return curr->next_fd; +} + +// 파일 객체를 검색하는 함수 +struct file *process_get_file(int fd) +{ + struct thread *curr = thread_current(); + struct file **fdt = curr->fdt; + + /* 파일 디스크립터에 해당하는 파일 객체를 리턴 */ + /* 없을 시 NULL 리턴 */ + if (fd < 2 || fd >= FDT_COUNT_LIMIT) + return NULL; + return fdt[fd]; +} + +// 파일 디스크립터 테이블에서 객체를 제거하는 함수 +void process_close_file(int fd) +{ + struct thread *curr = thread_current(); + struct file **fdt = curr->fdt; + if (fd < 2 || fd >= FDT_COUNT_LIMIT) // 만약 fd 가 2보다 작거나 128 크기 이상이라면 오류 발생 + return NULL; + fdt[fd] = NULL; } \ No newline at end of file diff --git a/userprog/syscall.c b/userprog/syscall.c index 1928191..ca1d442 100644 --- a/userprog/syscall.c +++ b/userprog/syscall.c @@ -7,9 +7,32 @@ #include "userprog/gdt.h" #include "threads/flags.h" #include "intrinsic.h" +#include "filesys/filesys.h" +#include "filesys/file.h" +#include "userprog/process.h" +#include "threads/synch.h" +// 오류 를 일으켜서 추가한 라이브러리. +#include "devices/input.h" +#include "lib/kernel/stdio.h" +#include "threads/palloc.h" void syscall_entry (void); void syscall_handler (struct intr_frame *); +void check_address(void *addr); +void halt(void); +void exit(int status); +bool create(const char *file, unsigned initial_size); +bool remove(const char *file); +int exec(const char *cmd_line); +int wait(int pid); +int open(const char *file_name); +int filesize(int fd); +int read(int fd, void *buffer, unsigned size); +int write(int fd, const void *buffer, unsigned size); +void seek(int fd, unsigned position); +unsigned tell(int fd); +void close(int fd); +tid_t fork(const char *thread_name, struct intr_frame *f); /* System call. * @@ -35,12 +58,234 @@ syscall_init (void) { * mode stack. Therefore, we masked the FLAG_FL. */ write_msr(MSR_SYSCALL_MASK, FLAG_IF | FLAG_TF | FLAG_DF | FLAG_IOPL | FLAG_AC | FLAG_NT); + lock_init(&filesys_lock); } /* The main system call interface */ void syscall_handler (struct intr_frame *f UNUSED) { // TODO: Your implementation goes here. - printf ("system call!\n"); - thread_exit (); + int systemcall_num = f->R.rax; + printf("%d\n", systemcall_num); + + switch (systemcall_num) + { + case SYS_HALT: + halt(); + break; + case SYS_EXIT: + exit(f->R.rdi); + break; + case SYS_FORK: + f->R.rax = fork(f->R.rdi, f); + break; + case SYS_EXEC: + f->R.rax = exec(f->R.rdi); + break; + case SYS_WAIT: + f->R.rax = wait(f->R.rdi); + break; + case SYS_CREATE: + f->R.rax = create(f->R.rdi, f->R.rsi); + break; + case SYS_REMOVE: + f->R.rax = remove(f->R.rdi); + break; + case SYS_OPEN: + f->R.rax = open(f->R.rdi); + break; + case SYS_FILESIZE: + f->R.rax = filesize(f->R.rdi); + break; + case SYS_READ: + f->R.rax = read(f->R.rdi, f->R.rsi, f->R.rdx); + break; + case SYS_WRITE: + f->R.rax = write(f->R.rdi, f->R.rsi, f->R.rdx); + break; + case SYS_SEEK: + seek(f->R.rdi, f->R.rsi); + break; + case SYS_TELL: + f->R.rax = tell(f->R.rdi); + break; + case SYS_CLOSE: + close(f->R.rdi); + } +} + +void check_address(void *addr){ + if (addr == NULL) + exit(-1); + if (!is_user_vaddr(addr)) + exit(-1); + if (pml4_get_page(thread_current()->pml4, addr) == NULL) + exit(-1); + // if (addr == NULL || !(is_user_vaddr(addr))||pml4_get_page(cur->pml4, addr) == NULL){ + // exit(-1); + // } +} + +// pintos를 종료시키는 시스템 콜 +void halt(void){ + power_off(); // 핀토스를 종료시키는 함수 } + +// 현재 프로세스를 종료시키는 시스템 콜 +void exit(int status){ + struct thread *cur = thread_current(); + cur->exit_status = status; + printf("%s: exit(%d)\n",thread_name(), status); + thread_exit(); +} + +//파일을 생성하는 시스템 콜 +bool create(const char *file, unsigned initial_size){ + check_address(file); + return filesys_create(file,initial_size); // 파일 이름과 파일 사이즈를 인자 값으로 받아 파일을 생성하는 함수 +} + +//파일을 삭제하는 시스템 콜 +bool remove(const char *file){ + check_address(file); + return filesys_remove(file); // 파일 이름에 해당하는 파일을 제거하는 함수 +} + +int exec(const char *cmd_line) +{ + check_address(cmd_line); + + // 새 스레드를 생성하지 않고 process_exec을 호출한다. + + char *cmd_line_copy; // filename으로 const char* 복사본을 만든다. + cmd_line_copy = palloc_get_page(0); + if (cmd_line_copy == NULL) // 메모리 할당 실패시 exit(-1) + exit(-1); + strlcpy(cmd_line_copy, cmd_line, PGSIZE); // cmd_line을 복사한다. + + if (process_exec(cmd_line_copy) == -1) + exit(-1); // 실패 시 status -1로 종료한다. +} + +int wait(int pid) +{ + return process_wait(pid); +} + +// 파일을 열 때 사용하는 시스템 콜 +int open(const char *file_name) +{ + check_address(file_name); + struct file *file = filesys_open(file_name); + if (file == NULL) + return -1; + int fd = process_add_file(file); + if (fd == -1) // 여기에 땀 있었음.(닦아줌) + file_close(file); + return fd; +} + +// 파일의 크기를 알려주는 시스템 콜 +int filesize(int fd) +{ + struct file *file = process_get_file(fd); + if (file == NULL) + return -1; + return file_length(file); +} + +// 열린 파일의 데이터를 읽는 시스템 콜 +int read(int fd, void *buffer, unsigned size) +{ + check_address(buffer); + + char *ptr = (char *)buffer; + int bytes_read = 0; + + lock_acquire(&filesys_lock); // 락을 요구합니다. + if(fd == STDIN_FILENO) + { + for (int i = 0; i < size; i++) + { + *ptr++ = input_getc(); + bytes_read++; + } + lock_release(&filesys_lock); + } + else + { + if (fd < 2) + { + lock_release(&filesys_lock); + return -1; + } + struct file *file = process_get_file(fd); + if (file == NULL) + { + lock_release(&filesys_lock); + return -1; + } + bytes_read = file_read(file, buffer, size); + lock_release(&filesys_lock); + } + return bytes_read; +} + +// 열린 파일의 데이터를 기록 시스템 콜 +int write(int fd, const void *buffer, unsigned size) +{ + check_address(buffer); + int bytes_write = 0; + if (fd == STDOUT_FILENO) + { + putbuf(buffer, size); + bytes_write = size; + } + else + { + if (fd < 2) + return -1; + struct file *file = process_get_file(fd); + if (file == NULL) + return -1; + lock_acquire(&filesys_lock); + bytes_write = file_write(file, buffer, size); + lock_release(&filesys_lock); + } + return bytes_write; +} + + +// 열린 파일의 위치를 이동하는 시스템 콜 +void seek(int fd, unsigned position) +{ + struct file *file = process_get_file(fd); + if (file == NULL) + return; + file_seek(file, position); +} + +// 열린 파일의 위치를 알려주는 시스템 콜 +unsigned tell(int fd) +{ + struct file *file = process_get_file(fd); + if (file == NULL) + return; + return file_tell(file); +} + +// 열린 파일을 닫는 시스템 콜 +void close(int fd) +{ + struct file *file = process_get_file(fd); + if (file == NULL) + return; + file_close(file); + process_close_file(fd); +} + + +tid_t fork(const char *thread_name, struct intr_frame *f) +{ + return process_fork(thread_name, f); +} \ No newline at end of file