diff --git a/src/userprog/process.c b/src/userprog/process.c index 6c82064..6af78e2 100644 --- a/src/userprog/process.c +++ b/src/userprog/process.c @@ -19,11 +19,13 @@ #include "threads/vaddr.h" #include "threads/malloc.h" +#define FD_MIN 2 /* Min value for file descriptors. */ + /* Structure for arguments. */ struct arguments { - int argc; /* Number of arguments. */ - char **argv; /* Array of arguments. */ + int argc; /* Number of arguments. */ + char **argv; /* Array of arguments. */ }; static thread_func start_process NO_RETURN; @@ -105,6 +107,7 @@ start_process (void *arguments) else curr->status |= PROCESS_FAIL; curr->exec_file = exec_file; + curr->fd_next = FD_MIN; list_init (&curr->file_list); /* If load failed, quit. */ @@ -166,6 +169,13 @@ process_exit (void) proc->status |= PROCESS_EXIT; list_remove (&proc->elem); file_close (proc->exec_file); + for (e = list_begin (&proc->file_list); e != list_end (&proc->file_list);) + { + struct process_file *pfe = list_entry (e, struct process_file, elem); + e = list_next (e); + file_close (pfe->file); + free (pfe); + } struct thread *curr = thread_current (); uint32_t *pd; @@ -225,6 +235,41 @@ process_find_child (struct process *proc, pid_t pid) } return NULL; } + +/* Returns a process' file by the file descriptor. */ +struct file * +process_get_file (int fd) +{ + struct list *list = &process_current ()->file_list; + struct list_elem *e; + for (e = list_begin (list); e != list_end (list); e = list_next (e)) + { + struct process_file *pfe = list_entry (e, struct process_file, elem); + if (pfe->fd == fd) + return pfe->file; + } + return NULL; +} + +/* Sets the file into the current process and returns the file descriptor. */ +int +process_set_file (struct file *file) +{ + /* Create a file element. */ + struct process_file *pfe; + pfe = (struct process_file *) malloc (sizeof (struct process_file)); + if (pfe == NULL) + return -1; + + /* Initialize the file element. */ + struct process *curr = process_current (); + pfe->fd = curr->fd_next++; + pfe->file = file; + list_push_back (&curr->file_list, &pfe->elem); + + /* Return the file descriptor. */ + return pfe->fd; +} /* We load ELF binaries. The following definitions are taken from the ELF specification, [ELF1], more-or-less verbatim. */ diff --git a/src/userprog/process.h b/src/userprog/process.h index 0cf4b28..56b17d8 100644 --- a/src/userprog/process.h +++ b/src/userprog/process.h @@ -26,6 +26,7 @@ struct process int status; /* Process status. */ int exit_code; /* Exit code. */ bool is_waiting; /* Whether parent is waiting or not. */ + int fd_next; /* File descriptor tracker. */ }; /* A file held by some process. */ @@ -42,5 +43,7 @@ void process_exit (void); void process_activate (void); struct process *process_current (void); struct process *process_find_child (struct process *proc, pid_t pid); +struct file *process_get_file (int fd); +int process_set_file (struct file * file); #endif /* userprog/process.h */ diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index 57334c1..b89d593 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -249,10 +249,29 @@ syscall_remove (const char *file) return success; } +/* Opens the file. Returns a nonnegative integer handle, + a file descriptor, or -1 if the file could not be opened. */ static int syscall_open (const char *file) { - return 0; + /* Check the validity. */ + validate_ptr (file); + + /* Open the file. */ + lock_acquire (&filesys_lock); + struct file *f = filesys_open (file); + if (f == NULL) + { + lock_release (&filesys_lock); + return -1; + } + + /* Set the file. */ + int fd = process_set_file (f); + + /* Return the file descriptor. */ + lock_release (&filesys_lock); + return fd; } static int