summaryrefslogtreecommitdiffstats
path: root/userprog/syscall.c
diff options
context:
space:
mode:
Diffstat (limited to 'userprog/syscall.c')
-rw-r--r--userprog/syscall.c62
1 files changed, 58 insertions, 4 deletions
diff --git a/userprog/syscall.c b/userprog/syscall.c
index 7f8c397..14cbaab 100644
--- a/userprog/syscall.c
+++ b/userprog/syscall.c
@@ -14,7 +14,8 @@
14#include "userprog/pagedir.h" 14#include "userprog/pagedir.h"
15#include "userprog/process.h" 15#include "userprog/process.h"
16#include "userprog/syscall.h" 16#include "userprog/syscall.h"
17#include "lib/user/syscall.h" 17#include "vm/mmap.h"
18#include "vm/page.h"
18 19
19#define STACK_SLOT_SIZE sizeof(int) 20#define STACK_SLOT_SIZE sizeof(int)
20 21
@@ -226,8 +227,8 @@ syscall_handler (struct intr_frame *f)
226 goto fail; 227 goto fail;
227 } 228 }
228 syscall_sp = sp; 229 syscall_sp = sp;
229 result = fp (sp, &segfault); 230 result = fp (sp, &segfault);
230 if (segfault) 231 if (segfault)
231 goto fail; 232 goto fail;
232 f->eax = result; 233 f->eax = result;
233 return; 234 return;
@@ -574,11 +575,64 @@ syscall_close (void *sp, bool *segfault)
574static int 575static int
575syscall_mmap (void *sp, bool *segfault) 576syscall_mmap (void *sp, bool *segfault)
576{ 577{
577 return 0; 578 int fd;
579 void *addr, *offset;
580 struct file *file, *file2;
581 off_t len;
582
583 /* get arguments */
584 if (! copy_from_user (&fd, STACK_ADDR (sp,1)) ||
585 ! copy_from_user (&addr, STACK_ADDR (sp, 2))) {
586 *segfault = true;
587 return -1;
588 }
589
590 /* address must be valid and page-aligned */
591 if (addr == NULL || pg_ofs (addr))
592 return -1;
593
594 /* file descriptors 0 and 1 are reserved */
595 if (fd == 0 || fd == 1)
596 return -1;
597
598 /* get file */
599 file = process_get_file (fd);
600 if (file == NULL)
601 return -1;
602
603 /* file length must be positiv */
604 len = file_length (file);
605 if (len <= 0)
606 return -1;
607
608 /* check if the pages don't overlap any existing pages */
609 offset = addr;
610 while(offset < addr + len)
611 {
612 if (page_table_fetch (&thread_current ()->page_table, offset))
613 return -1;
614 offset += PGSIZE;
615 }
616
617 process_lock_filesys ();
618 file2 = file_reopen (file);
619 process_unlock_filesys ();
620
621 return (file2 == NULL) ? -1 :
622 mmap_table_insert (&process_current()->mmap_table, addr, file2, len);
578} 623}
579 624
580static int 625static int
581syscall_munmap (void *sp, bool *segfault) 626syscall_munmap (void *sp, bool *segfault)
582{ 627{
628 mapid_t mapping;
629
630 /* get arguments */
631 if (! copy_from_user (&mapping, STACK_ADDR (sp,1))) {
632 *segfault = true;
633 return 0;
634 }
635
636 mmap_table_remove (&process_current()->mmap_table, mapping);
583 return 0; 637 return 0;
584} 638}