diff --git a/Makefile.build b/Makefile.build index 2fb7073287800f5c80383e3a10287304011d6a18..a736cc709ae1bf2eba8f4af0079f10c6b39cce67 100644 --- a/Makefile.build +++ b/Makefile.build @@ -68,6 +68,7 @@ userprog_SRC += userprog/syscall_halt.c userprog_SRC += userprog/syscall_wait.c userprog_SRC += userprog/syscall_create.c userprog_SRC += userprog/syscall_write.c +userprog_SRC += userprog/file_descriptors_map.c # No virtual memory code yet. #vm_SRC = vm/file.c # Some file. diff --git a/examples/exit b/examples/exit new file mode 100755 index 0000000000000000000000000000000000000000..a6569c49fe418705632d054e3e5337cf83e9da29 Binary files /dev/null and b/examples/exit differ diff --git a/examples/touch b/examples/touch index 0d81b3ea3dccb90bf0a39ad1b64cfed65f0da0ca..f68795f860f0e445ef5ee631e95ee05b7bc9e8c5 100755 Binary files a/examples/touch and b/examples/touch differ diff --git a/userprog/file_descriptors_map.c b/userprog/file_descriptors_map.c new file mode 100644 index 0000000000000000000000000000000000000000..7ab7943c883ce468a76190a336fbfc7ef8172028 --- /dev/null +++ b/userprog/file_descriptors_map.c @@ -0,0 +1,55 @@ +/* + * File Descriptors mapper + * + * Authored by Joshua Saxby + */ +#include <stddef.h> +#include "filesys/filesys.h" +#include "system_calls.h" + +// this means we can't have more than 255 open file handles at a time +#define MAX_FILE_POINTERS 255 + +static struct file* FILE_POINTERS_MAP[MAX_FILE_POINTERS] = {0}; + +struct file * get_associated_file_pointer(int fd) { + switch (fd) { + case 0: // keyboard (stdin) + case 1: // console (stdout) + case 2: // console (stderr) + return NULL; + default: + return FILE_POINTERS_MAP[fd - 3]; // exclude special fds + } +} + +int associate_new_file_descriptor(struct file* file_pointer) { + // if we have been passed NULL, refuse (it's silly!) + if (file_pointer == NULL) return -1; + // find the first decriptor which points to NULL + for (size_t i = 0; i < MAX_FILE_POINTERS; i++) { + if (FILE_POINTERS_MAP[i] == NULL) { + FILE_POINTERS_MAP[i] = file_pointer; + return i + 3; // exclude special fds + } + } + // if we got here, we've run out of spare slots, return failure + return -1; +} + +bool disassociate_file_descriptor(int fd) { + // clear the descriptor to NULL + switch (fd) { + case 0: // keyboard (stdin) + case 1: // console (stdout) + case 2: // console (stderr) + return false; + default: + if (FILE_POINTERS_MAP[fd - 3] != NULL) { // exclude special fds + FILE_POINTERS_MAP[fd - 3] = NULL; + return true; + } else { + return false; + } + } +} diff --git a/userprog/system_calls.h b/userprog/system_calls.h index be83270c704309e07150583226503aafc2ce1c82..1d56a93e4767fdde504892f2d601684463945baa 100644 --- a/userprog/system_calls.h +++ b/userprog/system_calls.h @@ -1,3 +1,4 @@ +#include "filesys/file.h" #include "threads/interrupt.h" /* @@ -46,3 +47,16 @@ void syscall_write(struct intr_frame *f); * NOTE: There are more system calls implemented by Pintos but we are not * implementing them because the assignment brief does not ask of it. */ + +/* + * special additional stuff for handling file descriptors because they're annoying + */ + +// returns NULL if the given file descriptor does not match a known file +struct file * get_associated_file_pointer(int fd); +// remembers the given file, and returns int of file descriptor +// returns -1 if could not store it (means we've opened too many files) +int associate_new_file_descriptor(struct file* file_pointer); +// disassociates the given file descriptor (and its associated pointer) +// returns false if this failed for some reason +bool disassociate_file_descriptor(int fd);