summaryrefslogtreecommitdiffstats
path: root/src/userprog/syscall.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/userprog/syscall.c')
-rw-r--r--src/userprog/syscall.c46
1 files changed, 44 insertions, 2 deletions
diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c
index 370c89b..5e5a6f1 100644
--- a/src/userprog/syscall.c
+++ b/src/userprog/syscall.c
@@ -4,6 +4,10 @@
#include "threads/interrupt.h"
#include "threads/thread.h"
+#include "threads/init.h"
+#include "filesys/filesys.h"
+#include "filesys/off_t.h"
+
static void syscall_handler (struct intr_frame *);
void
@@ -12,9 +16,47 @@ syscall_init (void)
intr_register_int (0x30, 3, INTR_ON, syscall_handler, "syscall");
}
+// cast to TYPE and deref argument N from f->esp
+#define INTR_ESP(N, TYPE) *(TYPE *)(f->esp+(4*(N)))
+
static void
syscall_handler (struct intr_frame *f UNUSED)
{
- printf ("system call!\n");
- thread_exit ();
+ int syscall_number = INTR_ESP(0, int);
+ switch (syscall_number) {
+ case 0:
+ // halt
+ power_off ();
+ break;
+ case 1:
+ // exit
+ break;
+ case 4:
+ // create
+ ; // empty statement because c-grammar doesn't allow declarations following labels
+ printf("kernel: create\n");
+ char *filename = INTR_ESP(1, char *);
+ printf("create: read filename '%s'\n", filename);
+ off_t initial_size = INTR_ESP(2, off_t);
+ printf("create: read initial_size '%d'\n", initial_size);
+ f->eax = filesys_create(filename, initial_size);
+ printf("create: result (%d) put in f->eax\n", f->eax);
+ break;
+ case 6:
+ // open
+ break;
+ case 8:
+ // read
+ break;
+ case 9:
+ // write
+ printf ("printf: %s", INTR_ESP(2, char *));
+ break;
+ case 12:
+ // close
+ break;
+ default:
+ printf ("kernel: unknown syscall '%d'\n", syscall_number);
+ break;
+ }
}