From 197ad95eb9288ad1d2684ea530397da789a606e3 Mon Sep 17 00:00:00 2001
From: Joshua Saxby <joshua.a.saxby@gmail.com>
Date: Wed, 4 Dec 2019 11:42:47 +0000
Subject: [PATCH] Added a very basic system for associating file descriptors
 with file pointers

---
 Makefile.build                  |   1 +
 examples/exit                   | Bin 0 -> 36776 bytes
 examples/touch                  | Bin 37028 -> 37032 bytes
 userprog/file_descriptors_map.c |  55 ++++++++++++++++++++++++++++++++
 userprog/system_calls.h         |  14 ++++++++
 5 files changed, 70 insertions(+)
 create mode 100755 examples/exit
 create mode 100644 userprog/file_descriptors_map.c

diff --git a/Makefile.build b/Makefile.build
index 2fb7073..a736cc7 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
GIT binary patch
literal 36776
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

literal 0
HcmV?d00001

diff --git a/examples/touch b/examples/touch
index 0d81b3ea3dccb90bf0a39ad1b64cfed65f0da0ca..f68795f860f0e445ef5ee631e95ee05b7bc9e8c5 100755
GIT binary patch
delta 189
zcmZ3okZHw2rU?p+H#RErX)y9kHqele<<VhaU|^ca!1{=Rfq{`{H<-u5_6@}2o1Cf<
z&lofLsK!jj)tlord)OHBH^0&MVr2Zg+1&6m6XTr8+9rP)xi@Q?e&%9y*(~c2%E8FC
zx!7Y1KYIkoAO`cv1#wc7JtEYZnYkG^7euVl+AP)F#>04P^1^;)CdS0c$NJS69Vfr-
nS7#M!Vqo|&*>QsKWSt2Dj4G3DC#W;>OirDk&iH0>?*wrGy>K|<

delta 169
zcmZ3nkZH+6rU?p+S2im0X)tn3Hqele<<MbZU|^ca!1{=Rfq{`@H<-u5_6@}2nw+W;
z&lolNsK!jjm7C)=d)OFrH^0&MVr2Zi+1&6m6XUGO+9rP)IX7#Xe&%9y+AQl3%E8F8
zx!7Y1KV#TrjR<!}$<0L(YqT~iG`H|D-k7|!UzzED!sJu^YK-=iKlZCL3QU%qpw6f;
V*>Qq8Bgf>-3F?e5CQqCo4ge<HH6j22

diff --git a/userprog/file_descriptors_map.c b/userprog/file_descriptors_map.c
new file mode 100644
index 0000000..7ab7943
--- /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 be83270..1d56a93 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);
-- 
GitLab