summaryrefslogtreecommitdiffstats
path: root/src/userprog
diff options
context:
space:
mode:
Diffstat (limited to 'src/userprog')
-rw-r--r--src/userprog/syscall.c77
1 files changed, 65 insertions, 12 deletions
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