From 5cace94ee99bbfa107a01558871762b64b7af0da Mon Sep 17 00:00:00 2001
From: s2-fidan <Sude2.Fidan@live.uwe.ac.uk>
Date: Thu, 1 Dec 2022 00:55:09 +0000
Subject: [PATCH] ERROR CORRECTION

---
 src/threads/thread.h   |   3 +
 src/userprog/process.c |   2 +-
 src/userprog/syscall.c | 126 ++++++++++++++++++++++++++++++++++++++++-
 src/userprog/syscall.h |  11 ++++
 4 files changed, 138 insertions(+), 4 deletions(-)

diff --git a/src/threads/thread.h b/src/threads/thread.h
index c1e7aab..f5988da 100644
--- a/src/threads/thread.h
+++ b/src/threads/thread.h
@@ -96,6 +96,9 @@ struct thread
 #ifdef USERPROG
     /* Owned by userprog/process.c. */
     uint32_t *pagedir;                  /* Page directory. */
+    uint8_t *current_esp;               /* The current value of the user program’s stack pointer.
+                                           A page fault might occur in the kernel, so we might
+                                           need to store esp on transition to kernel mode*/
 #endif
 
     /* Owned by thread.c. */
diff --git a/src/userprog/process.c b/src/userprog/process.c
index 8593431..e0f4408 100644
--- a/src/userprog/process.c
+++ b/src/userprog/process.c
@@ -45,7 +45,7 @@ process_execute(const char *file_name)
   /* Parse first argument as program name */
   strlcpy(program, file_name, file_name_length);
   strtok_r(program, " ", &ptr);
-  printf("\nProgram name: %s\n", program) ;
+  printf("\nProgram name: %s\n\n", program) ;
 
   /* Create a new thread to execute FILE_NAME. */
   tid = thread_create(file_name, PRI_DEFAULT, start_process, file_copy);
diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c
index 0463515..e32359c 100644
--- a/src/userprog/syscall.c
+++ b/src/userprog/syscall.c
@@ -1,4 +1,5 @@
 #include "userprog/syscall.h"
+#include <stdbool.h>
 #include <stdio.h>
 #include <syscall-nr.h>
 #include "threads/interrupt.h"
@@ -6,16 +7,135 @@
 
 static void syscall_handler (struct intr_frame *);
 
+/*System call initializer*/
 void
 syscall_init (void) 
 {
   intr_register_int (0x30, 3, INTR_ON, syscall_handler, "syscall");
 }
 
-
+/*Handler for system commands.*/
 static void
 syscall_handler (struct intr_frame *f UNUSED)
 {
-  printf ("system call!\n");
-  thread_exit ();
+  /* References: J,Choi(2014), pintos. Available from: https://github.com/wookayin/pintos [accessed on 27/11/22]*/
+  int syscall_number;
+  ASSERT( sizeof(syscall_number) == 4 ); /*assuming x86*/
+
+  /*The system call number is in the 32-bit word at the caller's stack pointer.*/
+  read(f->esp, &syscall_number, sizeof(syscall_number));
+
+  /*Store the esp, which is needed in the page fault handler.*/
+  thread_current()->current_esp = f->esp;
+
+  switch (syscall_number) {
+  case SYS_HALT: // 0
+    {
+      /*Terminate PintOS*/
+      syscall_halt();
+      break;
+    }
+    case SYS_WAIT: // 2
+    {
+      tid_t tid;
+      /*Get argument*/
+      read(f->esp + 4, &tid, sizeof(tid_t));
+      /*Wait for child process*/
+      f->eax = syscall_wait(tid);
+      break;
+    }
+
+    case SYS_CREATE: // 3
+    {
+      const char* file_name;
+      unsigned initial_size;
+
+      /*Get file name and size*/
+      read(f->esp + 4, &file_name, sizeof(file_name));
+      read(f->esp + 8, &initial_size, sizeof(initial_size));
+
+      /*Create file*/
+      f->eax =  syscall_create(file_name, initial_size);
+      break;
+    }
+
+    case SYS_REMOVE: // 4
+    {
+      const char* file_name;
+      bool return_code;
+
+      /*Get file name*/
+      read(f->esp + 4, &file_name, sizeof(file_name));
+
+      /*Remove file*/
+      f->eax = syscall_remove(file_name);
+      break;
+    }
+    /* Unimplemented system calls */
+    default:
+        printf("ERROR: system call ( %d ) has not implemented!\n", syscall_number);
+
+    /* Terminate. */
+    syscall_exit(-1);
+    break;
+  }
+}
+
+
+/********SYSTEMCALLS********/
+
+/* Halt */
+void syscall_halt(void) {
+  shutdown_power_off(); /* From shutdown.h */
+}
+
+/* Exit */
+void syscall_exit(int status) {
+  struct thread *current_process=thread_current();
+  current_process->process_exit_status = status;
+
+  printf("%s: exit(%d)\n",current_process->name,status);
+
+  thread_exit();
+}
+
+/* Wait */
+int syscall_wait(tid_t tid)
+{
+  return process_wait(tid);
+}
+
+/* Create File */
+bool syscall_create(const char* file_name, unsigned initial_size) {
+  bool if_created = false;
+  if( filesys_create(file_name, initial_size)==true){
+    if_created = true;
+  }
+  return if_created;
+}
+
+/* Remove File */
+bool syscall_remove(const char* file_name) {
+  bool if_removed = false;
+  if( filesys_remove(file_name)==true){
+    if_removed = true;
+  }
+  return if_removed;
+}
+
+
+/****OTHER FUNCTIONS****/
+static int read(void *src, void *dst, size_t bytes)
+{
+  int32_t value;
+  size_t i;
+  for (i = 0; i < bytes; i++)
+  {
+    value = get_user(src + i);
+    if (value == -1) // segfault or invalid memory access
+      fail_invalid_access();
+
+    *(char *)(dst + i) = value & 0xff;
+  }
+  return (int)bytes;
 }
diff --git a/src/userprog/syscall.h b/src/userprog/syscall.h
index 9059096..7289c24 100644
--- a/src/userprog/syscall.h
+++ b/src/userprog/syscall.h
@@ -1,6 +1,17 @@
 #ifndef USERPROG_SYSCALL_H
 #define USERPROG_SYSCALL_H
+#include "threads/thread.h"
+#include <stdbool.h>
+#include <stddef.h>
 
 void syscall_init (void);
 
+void syscall_halt(void);
+void syscall_exit(int status);
+int syscall_wait(tid_t tid);
+bool syscall_create(const char* file_name, unsigned initial_size);
+bool syscall_remove(const char* file_name);
+
+static int read(void *src, void *dst, size_t bytes);
+
 #endif /* userprog/syscall.h */
-- 
GitLab