diff --git a/userprog/syscall_read.c b/userprog/syscall_read.c index bd6c2dfbf379f22aa79adeec3202217ecbb70072..67f7d9858ea87ecc23b717a9b8dee1353d323abe 100644 --- a/userprog/syscall_read.c +++ b/userprog/syscall_read.c @@ -3,10 +3,40 @@ * * Authored by Joshua Saxby */ -#include "filesys/filesys.h" +#include <stddef.h> +#include "devices/input.h" +#include "filesys/file.h" #include "system_calls.h" #include "threads/interrupt.h" void syscall_read(struct intr_frame *f) { - (void*)0; + // first argument is syscall code (already handled) + int fd = *((int*)f->esp + 1); // file descriptor is second argument + char* buffer = (void*)(*((int*)f->esp + 2)); // buffer is third argument + unsigned size = *((unsigned*)((int*)f->esp + 3)); // size to read is fourth + // reading from stdin (keyboard) is a special case + switch (fd) { + case 0: { + // read from keyboard for as many bytes as requested + for (size_t i = 0; i < size; i++) { + *(buffer + i) = input_getc(); + } + f->eax = size; + break; + } + case 1: // stdout + case 2: // stderr + f->eax = -1; // it is a mistake to attempt to read from stdout or stderr + break; + default: { + // otherwise, we need to read from a file denoted by fd + struct file* file_to_read = get_associated_file_pointer(fd); + if (file_to_read == NULL) { + f->eax = -1; // invalid file descriptor + break; + } + f->eax = file_read(file_to_read, buffer, size); + break; + } + } }