summaryrefslogtreecommitdiffstats
path: root/src/userprog/syscall.c
diff options
context:
space:
mode:
authorGustav Sörnäs <gustav@sornas.net>2021-02-05 15:41:02 +0100
committerGustav Sörnäs <gustav@sornas.net>2021-02-05 15:41:02 +0100
commit8042c019ffb37e9d17cca14be0944d730f680d5f (patch)
tree9b092c5054865b0e8a606a37cb201d326d255d6c /src/userprog/syscall.c
parent62b9f1b6b3fed01652153c5259427db97fe75e2c (diff)
downloadpintos-8042c019ffb37e9d17cca14be0944d730f680d5f.tar.gz
implement open()
Diffstat (limited to 'src/userprog/syscall.c')
-rw-r--r--src/userprog/syscall.c44
1 files changed, 41 insertions, 3 deletions
diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c
index 8e5593f..e72ee0b 100644
--- a/src/userprog/syscall.c
+++ b/src/userprog/syscall.c
@@ -4,9 +4,10 @@
#include "threads/interrupt.h"
#include "threads/thread.h"
-#include "threads/init.h"
#include "filesys/filesys.h"
#include "filesys/off_t.h"
+#include "threads/init.h"
+#include "threads/malloc.h"
static void syscall_handler (struct intr_frame *);
@@ -28,6 +29,42 @@ create (const char *filename, off_t initial_size)
return filesys_create (filename, initial_size);
}
+static int
+open (const char *filename)
+{
+ struct thread *t = thread_current ();
+
+ if (t->max_files == 0) {
+ t->max_files = 128;
+ printf("[%s] open: allocating %d file descriptors\n", t->name, t->max_files);
+ t->files = (struct fd *) calloc (t->max_files, sizeof (struct fd));
+ }
+
+ if (t->num_files == t->max_files) {
+ // not enough space for more file descriptors
+ printf("[%s] open: too many file descriptors\n", t->name);
+ return -1;
+ }
+
+ struct file *file = filesys_open(filename);
+ if (!file) {
+ printf("[%s] open: couldn't find file %s\n", t->name, filename);
+ return -1;
+ }
+
+ for (int i = 0; i < t->max_files; i++) {
+ struct fd *fd = t->files + i;
+ if (!fd->active) {
+ fd->active = true;
+ fd->file = file;
+ return i + 2; // 0 and 1 are reserved for stdin and stdout
+ }
+ }
+ free(file);
+ printf("[%s] open: unable to find empty file descriptor\n", t->name);
+ return -1;
+}
+
static void
write (const char *buf)
{
@@ -40,7 +77,7 @@ write (const char *buf)
static void
syscall_handler (struct intr_frame *f UNUSED)
{
- int syscall_number = INTR_ESP(0, int);
+ int syscall_number = INTR_ESP (0, int);
switch (syscall_number) {
case 0:
// halt
@@ -51,10 +88,11 @@ syscall_handler (struct intr_frame *f UNUSED)
break;
case 4:
// create
- f->eax = create(INTR_ESP(1, char *), INTR_ESP(2, off_t));
+ f->eax = create (INTR_ESP (1, char *), INTR_ESP (2, off_t));
break;
case 6:
// open
+ f->eax = open (INTR_ESP (1, char *));
break;
case 8:
// read