diff --git a/src/threads/thread.c b/src/threads/thread.c
index 052302f8d417bbcce955ae4216fc297d956316a6..1b8407b1d072f7eafb977925b2a347b115bc655e 100644
--- a/src/threads/thread.c
+++ b/src/threads/thread.c
@@ -59,7 +59,8 @@ static unsigned thread_ticks;   /* # of timer ticks since last yield. */
    If true, use multi-level feedback queue scheduler.
    Controlled by kernel command-line option "-o mlfqs". */
 bool thread_mlfqs;
-
+/* file descriptor lock */
+struct lock file_lock;
 static void kernel_thread (thread_func *, void *aux);
 
 static void idle (void *aux UNUSED);
@@ -179,6 +180,7 @@ thread_create (const char *name, int priority,
   struct switch_entry_frame *ef;
   struct switch_threads_frame *sf;
   tid_t tid;
+  enum intr_level old_level;
 
   ASSERT (function != NULL);
 
@@ -191,6 +193,11 @@ thread_create (const char *name, int priority,
   init_thread (t, name, priority);
   tid = t->tid = allocate_tid ();
 
+  /* Prepare thread for first run by initializing its stack.
+     Do this atomically so intermediate values for the 'stack' 
+     member cannot be observed. */
+  old_level = intr_disable ();
+
   /* Stack frame for kernel_thread(). */
   kf = alloc_frame (t, sizeof *kf);
   kf->eip = NULL;
@@ -206,6 +213,21 @@ thread_create (const char *name, int priority,
   sf->eip = switch_entry;
   sf->ebp = 0;
 
+  intr_set_level (old_level);
+  /* Set Value */
+  t->next_fd = 2;
+  t->file_descriptor = palloc_get_page(0);
+  if(t->file_descriptor == NULL)
+	  return TID_ERROR;
+  t->childelem.next = NULL;
+  t->childelem.prev = NULL;
+  t->parent_thread = thread_current();
+  t->load_success = false;
+  t->process_exit = false;
+  sema_init(&(t->load_semaphore),0);
+  sema_init(&(t->exit_semaphore),0);
+  list_push_back(&(thread_current()->child_list),&(t->childelem));
+
   /* Add to run queue. */
   thread_unblock (t);
 
diff --git a/src/threads/thread.h b/src/threads/thread.h
index f5988dacd053e53c60127da18d60d8655ebe8ca7..e814f6b029d3a8eeabeb42a9f45be0b9306c54dd 100644
--- a/src/threads/thread.h
+++ b/src/threads/thread.h
@@ -81,8 +81,9 @@ typedef int tid_t;
    ready state is on the run queue, whereas only a thread in the
    blocked state is on a semaphore wait list. */
 struct thread
-  {
+{
     /* Owned by thread.c. */
+      struct list_elem childelem;
     tid_t tid;                          /* Thread identifier. */
     enum thread_status status;          /* Thread state. */
     char name[16];                      /* Name (for debugging purposes). */
@@ -104,9 +105,16 @@ struct thread
     /* Owned by thread.c. */
     unsigned magic;                     /* Detects stack overflow. */
     /* VALUE */
-	bool process_exit;
-	int process_exit_status;
-  };
+      struct file **file_descriptor;
+      int next_fd;
+      bool load_success;
+      bool process_exit;
+      int process_exit_status;
+      struct semaphore load_semaphore;
+      struct semaphore exit_semaphore;
+      struct thread *parent_thread;
+      struct list child_list;
+};
 
 /* If false (default), use round-robin scheduler.
    If true, use multi-level feedback queue scheduler.
diff --git a/src/userprog/process.c b/src/userprog/process.c
index e0f44086d4f4b6b53d10aafe4fae0993b4308a0d..4cbf0d6cb876caec341ecc27dc893e08b5edcb76 100644
--- a/src/userprog/process.c
+++ b/src/userprog/process.c
@@ -20,7 +20,8 @@
 
 static thread_func start_process NO_RETURN;
 static bool load(const char *cmdline, void (**eip)(void), void **esp);
-static void argument_pushing(char **parse, int count, void **esp);
+
+
 #define WORD_SIZE 4
 
 /* Starts a new thread running a user program loaded from
@@ -56,7 +57,78 @@ process_execute(const char *file_name)
   }
   return tid;
 }
-
+/* add file to file descriptor */
+int  process_add_file(struct file *f)
+{
+	struct file **fd = NULL;
+	int nextFd;
+
+	fd = thread_current()->file_descriptor;
+	nextFd = thread_current()->next_fd;
+
+	if(fd != NULL)
+	{
+		fd[nextFd] = f;
+		thread_current()->next_fd = thread_current()->next_fd+1;
+		return nextFd;
+	}
+	else
+	{
+		return -1;
+	}
+}
+/* get struct file  */
+struct file *process_get_file(int fd)
+{
+	struct file *pReturn;
+	if(fd < thread_current()->next_fd)
+	{
+		pReturn = thread_current()->file_descriptor[fd];
+		return pReturn;
+	}
+	else
+	{
+		return NULL;
+	}
+}
+/* close file function */
+void
+process_close_file(int fd)
+{
+	struct file *delete_file;
+	delete_file = process_get_file(fd);
+	if(delete_file != NULL)
+	{
+		file_close(delete_file);
+		thread_current()->file_descriptor[fd] = NULL;
+	}
+}
+/* get_child_process */
+struct thread *get_child_process(int pid)
+{
+	struct list *child_list=&(thread_current()->child_list);
+	struct thread *child_process = NULL;
+	struct list_elem *element;
+
+	/* find child process and return */
+	for(element=list_begin(child_list); element != list_end(child_list);            		element=list_next(element))
+	{
+		child_process = list_entry(element,struct thread,childelem);
+		if(child_process->tid == pid)
+			return child_process;
+	}
+	return NULL;     
+}
+/* remove_child_process */
+void
+remove_child_process(struct thread *cp)
+{
+	if(cp != NULL)
+	{
+		list_remove(&(cp->childelem));
+		palloc_free_page(cp);
+	}
+}
 /* A thread function that loads a user process and starts it
    running. */
 static void
@@ -88,8 +160,9 @@ start_process(void *file_name_)
   success = load(parse[0], &if_.eip, &if_.esp);
 
   argument_pushing(&parse, count, &if_.esp);
+  sema_up(&(thread_current()->load_semaphore));
 
-  hex_dump(if_.esp, if_.esp, PHYS_BASE - if_.esp, true);
+  //hex_dump(if_.esp, if_.esp, PHYS_BASE - if_.esp, true);
 
   /* If load failed, quit. */
   palloc_free_page(file_name);
@@ -451,7 +524,7 @@ load_segment(struct file *file, off_t ofs, uint8_t *upage,
   return true;
 }
 /* References: J,Choi(2014), pintos. Available from: https://github.com/wookayin/pintos [accessed on 23/11/22]*/
-static void
+void
 argument_pushing(char **parse, int count, void **esp)
 {
   int i, j;
@@ -490,13 +563,13 @@ argument_pushing(char **parse, int count, void **esp)
   for (i = count - 1; i >= 0; i--)
   {
     *esp -= 4;
-    **(char ***)esp = address[i];
+    **(char* **)esp = (char *)address[i];
   }
 
   /* Set **argv*/
   parse0_address = *(unsigned int *)esp;
   *esp -= 4;
-  **(char ***)esp = (char *)parse0_address;
+  **(char* **)esp = (char *)parse0_address;
 
   /* Set counter*/
   *esp -= 4;
@@ -547,3 +620,4 @@ install_page(void *upage, void *kpage, bool writable)
 }
 
 //--------------------------------------------------------------------
+
diff --git a/src/userprog/process.h b/src/userprog/process.h
index ee8fcf40271ae0bdd733b90d329680cb353ae6ac..86a806dc09e0688efb6bc763eca485a520dada1a 100644
--- a/src/userprog/process.h
+++ b/src/userprog/process.h
@@ -2,15 +2,21 @@
 #define USERPROG_PROCESS_H
 
 #include "threads/thread.h"
-typedef int pid_t;
 
-typedef int pit_t;
-#define PID_ERROR ((pid_t)-1)
-#define PID_INITIALIZING ((pid_t) -2)
+void argument_pushing(char **parse, int count, void **esp);
+
+struct thread *get_child_process(int pid);
+void remove_child_process(struct thread *cp);
+int process_add_file(struct file *f);
+struct file *process_get_file(int fd);
+void process_close_file(int fd);
+void process_exit(void);
 
 tid_t process_execute (const char *file_name);
 int process_wait (tid_t);
 void process_exit (void);
 void process_activate (void);
 
+
+
 #endif /* userprog/process.h */
diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c
index b83df34cdde93ff78cb1ca37503ddd0304cbb68f..01b74aa46b511befc920115d350c5e596b7e2599 100644
--- a/src/userprog/syscall.c
+++ b/src/userprog/syscall.c
@@ -5,6 +5,11 @@
 #include "threads/interrupt.h"
 #include "threads/thread.h"
 #include "threads/vaddr.h"
+#include <devices/shutdown.h>
+#include <filesys/filesys.h>
+#include <filesys/file.h>
+#include <userprog/process.h>
+#include <devices/input.h>
 
 static void syscall_handler (struct intr_frame *);
 
@@ -19,59 +24,41 @@ syscall_init (void)
 static void
 syscall_handler (struct intr_frame *f UNUSED)
 {
-  /* 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*/
+  int argument[5];
+  void *esp = f->esp;
 
-  /*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;
+  check_address(esp);
+  syscall_number = *(int *)esp;
 
   switch (syscall_number) {
-  case SYS_HALT: // 0
-    {
+    case SYS_HALT: // 0
       /*Terminate PintOS*/
       syscall_halt();
       break;
-    }
+    case SYS_EXIT: //1
+		  get_argument(esp,argument,1);
+		  syscall_exit(argument[0]);
+		  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);
+      get_argument(esp,argument,1);
+		  f->eax = syscall_wait(argument[0]);
       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);
+      get_argument(esp,argument,2);
+		  check_address((void *)argument[0]);
+		  f->eax = syscall_create((const char *)argument[0],(unsigned)argument[1]);
       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;
-    }
+      get_argument(esp,argument,1);
+		  check_address((void *)argument[0]);
+		  f->eax=syscall_remove((const char *)argument[0]);
+		  break;
+    case SYS_WRITE: //5
+		  get_argument(esp,argument,3);
+		  check_address((void *)argument[1]);
+		  f->eax = syscall_write(argument[0],(void *)argument[1],(unsigned)argument[2]);
+		  break;
     /* Unimplemented system calls */
     default:
         printf("ERROR: system call ( %d ) has not implemented!\n", syscall_number);
@@ -124,31 +111,52 @@ bool syscall_remove(const char* file_name) {
   return if_removed;
 }
 
-
+/* write file */
+int syscall_write(int fd, void *buffer, unsigned size)
+{
+	int write_size = 0;
+	struct file *current_file;
+
+	if(fd == 1)                    /*stdout */
+	{ 
+		putbuf((const char *)buffer,size);
+		write_size = size;
+	}
+	else
+	{
+		current_file = process_get_file(fd);
+		if(current_file != NULL)
+			write_size = file_write(current_file,(const void *)buffer,size);
+	}
+	return write_size;
+} 
 /****OTHER FUNCTIONS****/
-static int read(void *src, void *dst, size_t bytes)
+void
+check_address(void *addr)
 {
-  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
-    *(char *)(dst + i) = value & 0xff;
-  }
-  return (int)bytes;
+	uint32_t address=(unsigned int)addr;
+
+	uint32_t lowest=0x8048000;
+	uint32_t highest=0xc0000000;
+	if(address >= lowest && address < highest){
+		return;
+	}
+	else{
+		syscall_exit(-1);
+	}
 }
-/* Reads a byte at user virtual address UADDR.
-   UADDR must be below PHYS_BASE.
-   Returns the byte value if successful, -1 if a segfault
-   occurred. */
-static int
-get_user (const uint8_t *uaddr)
+/* get_argument function */
+void
+get_argument(void *esp, int *argument, int count)
 {
-  if(!is_user_vaddr(uaddr))
-    return -1;
-  int result;
-  asm ("movl $1f, %0; movzbl %1, %0; 1:"
-       : "=&a" (result) : "m" (*uaddr));
-  return result;
-}
+	int i;
+	void *stack_ptr=esp+4;
+	if(count > 0)
+	{
+		for(i=0; i<count; i++){
+			check_address(stack_ptr);
+			argument[i] = *(int *)stack_ptr;
+			stack_ptr = stack_ptr + 4;
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/userprog/syscall.h b/src/userprog/syscall.h
index e672e2a04c18790f9f4f2cc808450356061792e5..341169bd8b80edcbcce2148715e4dcf43614c3b9 100644
--- a/src/userprog/syscall.h
+++ b/src/userprog/syscall.h
@@ -9,21 +9,15 @@
 #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);
-static int get_user (const uint8_t *uaddr);
+void check_address(void *addr);
+void get_argument(void *esp, int *arg, int count);
 
 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);
+int syscall_write(int fd, void *buffer, unsigned size);
 
 #endif /* userprog/syscall.h */