From ed2f31c5978911d8afe9276e55b3be22bdd0547b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Fri, 5 Feb 2021 17:00:09 +0100 Subject: implement read() and refactor out get_file and get_fd --- src/userprog/syscall.c | 77 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 65 insertions(+), 12 deletions(-) (limited to 'src/userprog') diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index 0dd48b0..3a780c6 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -4,6 +4,8 @@ #include "threads/interrupt.h" #include "threads/thread.h" +#include "devices/input.h" +#include "filesys/file.h" #include "filesys/filesys.h" #include "filesys/off_t.h" #include "threads/init.h" @@ -58,29 +60,79 @@ open (const char *filename) return -1; } -static void -write (const char *buf) +static struct fd * +get_fd (struct thread *thread, int fd_i) { - printf ("printf: %s", buf); + if (!thread->fds) { + return NULL; + } + + return thread->fds + fd_i - 2; // -2 since 0 and 1 are reserved and not present in the array +} + +static struct file * +get_file (struct thread *thread, int fd_i) +{ + struct fd *fd = get_fd(thread, fd_i); + + if (!fd || !fd->active) { + printf("[%s] get_file: invalid file descriptor\n", thread->name); + return NULL; + } + + return fd->file; +} + +static int +read (int fd_i, void *buf, unsigned size) +{ + struct thread *thread = thread_current (); + + if (fd_i == 0) { + // stdin + int i; + for (i = 0; i < size; i++) { + ((char *)buf)[i] = input_getc (); + } + return i; + } else if (fd_i == 1) { + // can't read from stdout + printf("[%s] read: tried to read from stdout\n", thread->name); + return -1; + } + + struct file *file = get_file(thread, fd_i); + if (!file) { + return -1; + } + + int n = file_read (file, buf, size); + printf("%d/%d: %s\n", n, size, (char *)buf); + return n; +} + +static int +write (int fd_i, const void *buf, unsigned size) +{ + printf ("write: %s", (char *)buf); + return 0; } static void -close (int i) +close (int fd_i) { - struct thread *t = thread_current (); + struct thread *thread = thread_current (); - if (!t->fds) { - printf("[%s] close: no files have been opened\n", t->name); + struct fd *fd = get_fd(thread, fd_i); + if (!fd) { return; } - - struct fd *fd = t->fds + i - 2; // -2 since 0 and 1 are reserved and not present in the array if (!fd->active) { - printf("[%s] close: tried to close inactive file descriptor %d\n", t->name, i); + printf("[%s] close: tried to close inactive file descriptor %d\n", thread->name, fd_i); return; } - free(fd->file); + file_close (fd->file); fd->active = false; } @@ -109,10 +161,11 @@ syscall_handler (struct intr_frame *f UNUSED) break; case 8: // read + f->eax = read (INTR_ESP (1, int), INTR_ESP (2, void *), INTR_ESP (3, unsigned)); break; case 9: // write - write (INTR_ESP(2, char *)); + f->eax = write (INTR_ESP (1, int), INTR_ESP (2, const void *), INTR_ESP (3, unsigned)); break; case 12: // close -- cgit v1.2.1