From 4f670845ff9ab6c48bcb5f7bf4d4ef6dc3c3064b Mon Sep 17 00:00:00 2001 From: manuel Date: Tue, 27 Mar 2012 11:51:08 +0200 Subject: reorganize file structure to match the upstream requirements --- pintos-progos/userprog/syscall.c | 563 --------------------------------------- 1 file changed, 563 deletions(-) delete mode 100644 pintos-progos/userprog/syscall.c (limited to 'pintos-progos/userprog/syscall.c') diff --git a/pintos-progos/userprog/syscall.c b/pintos-progos/userprog/syscall.c deleted file mode 100644 index f8e0197..0000000 --- a/pintos-progos/userprog/syscall.c +++ /dev/null @@ -1,563 +0,0 @@ -#include -#include -#include "devices/input.h" -#include "devices/shutdown.h" -#include "filesys/file.h" -#include "filesys/filesys.h" -#include "filesys/inode.h" -#include "lib/string.h" -#include "threads/interrupt.h" -#include "threads/palloc.h" -#include "threads/synch.h" -#include "threads/thread.h" -#include "threads/vaddr.h" -#include "userprog/pagedir.h" -#include "userprog/process.h" -#include "userprog/syscall.h" - -#define STACK_SLOT_SIZE sizeof(int) - -/* Prototypes for Utilities */ -static int get_user (const uint8_t *uaddr); -static bool put_user (uint8_t *udst, uint8_t byte); -static void* memcpy_from_user (void *kaddr, void *uaddr, size_t bytes); -static void* memcpy_to_user (void *kaddr, void *addr, size_t bytes); -static void* copy_string_arg (void *usp, bool *segfault); -static void free_string_arg_buf (void *kbuf); - -/* 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) -{ - int result; - asm ("movl $1f, %0; " /* save eip in eax */ - "movzbl %1, %0; " /* read byte from user memory into eax */ - "1:" /* continue here on page fault, with eax set to -1 */ - : "=&a" (result) : "m" (*uaddr)); - return result; -} - -/* Writes BYTE to user address UDST. - UDST must be below PHYS_BASE. - Returns true if successful, false if a segfault occurred. */ -static bool -put_user (uint8_t *udst, uint8_t byte) -{ - int error_code; - asm ("movl $1f, %0;" /* save EIP in EAX */ - "movb %b2, %1;" /* write byte to user memory */ - "1:" /* continue here on page fault, with eax set to -1 */ - : "=&a" (error_code), "=m" (*udst) : "q" (byte)); - return error_code != -1; -} - -/* Copy bytes from user space; returns NULL if a segfault - occured, and kaddr otherwise */ -static void* -memcpy_from_user (void *kaddr, void *uaddr, size_t bytes) -{ - uint8_t* kp = kaddr; - size_t i; - if (! is_user_vaddr (uaddr) || - ! is_user_vaddr (uaddr + bytes - 1)) - return false; - for (i=0;iesp; - - /* The system call number and the arguments are on the stack */ - if (! copy_from_user (&syscall_nr,sp)) - goto fail; - switch (syscall_nr) { - case SYS_HALT: fp = syscall_halt; break; - case SYS_EXIT: fp = syscall_exit; break; - case SYS_EXEC: fp = syscall_exec; break; - case SYS_WAIT: fp = syscall_wait; break; - case SYS_CREATE: fp = syscall_create; break; - case SYS_REMOVE: fp = syscall_remove; break; - case SYS_OPEN: fp = syscall_open; break; - case SYS_FILESIZE: fp = syscall_filesize; break; - case SYS_READ: fp = syscall_read; break; - case SYS_WRITE: fp = syscall_write; break; - case SYS_SEEK: fp = syscall_seek; break; - case SYS_TELL: fp = syscall_tell; break; - case SYS_CLOSE: fp = syscall_close; break; - default: - goto fail; - } - result = fp (sp, &segfault); - if (segfault) - goto fail; - f->eax = result; - return; - - fail: - process_current()->exit_status = -1; - thread_exit (); -} - -/* Shutdown machine */ -static int -syscall_halt (void *sp UNUSED, bool *segfault UNUSED) -{ - shutdown (); - NOT_REACHED (); -} - -/* Exit current process with given exit code */ -static int -syscall_exit (void *sp, bool *segfault) -{ - int exit_status; - if (! copy_from_user (&exit_status, STACK_ADDR (sp,1))) { - *segfault = true; - return -1; - } - process_current()->exit_status = exit_status; - thread_exit (); - NOT_REACHED (); -} - -/* Spawn new process executing the supplied command */ -static int -syscall_exec (void *sp, bool *segfault) -{ - char *kbuf; - int result = TID_ERROR; - if ((kbuf = copy_string_arg (STACK_ADDR (sp, 1), segfault)) != NULL) { - result = process_execute (kbuf); - free_string_arg_buf (kbuf); - } - return result; -} - -/* Wait until specified process exits */ -static int -syscall_wait (void *sp, bool *segfault) -{ - tid_t arg; - if (! copy_from_user (&arg, STACK_ADDR (sp,1))) { - *segfault = true; - return 0; - } - return process_wait (arg); -} - -/* Create a new file with given initial size */ -static int -syscall_create (void *sp, bool *segfault) -{ - bool success = false; - char *fname; - int initial_size; - - if (! copy_from_user (&initial_size, STACK_ADDR (sp,2))) { - *segfault = true; - return false; - } - if ((fname = copy_string_arg (STACK_ADDR (sp, 1), segfault)) == NULL) - return false; - - process_lock_filesys (); - success = filesys_create (fname, initial_size); - process_unlock_filesys (); - free_string_arg_buf (fname); - return success; -} - -/* Remove name file, returns true if successful */ -static int -syscall_remove (void *sp, bool *segfault) -{ - bool success; - char *fname; - - if ((fname = copy_string_arg (STACK_ADDR (sp, 1), segfault)) == NULL) - return false; - process_lock_filesys (); - success = filesys_remove (fname); - process_unlock_filesys (); - free_string_arg_buf (fname); - return (int)success; -} - -/* Open file, returning non-negative file descriptor if successful */ -static int -syscall_open (void *sp, bool *segfault) -{ - char *fname; - int fd; - if ((fname = copy_string_arg (STACK_ADDR (sp, 1), segfault)) == NULL) - return false; - fd = process_open_file (fname); - free_string_arg_buf (fname); - return fd; -} - -/* Return size of file described by file descriptor */ -static int -syscall_filesize (void *sp, bool *segfault) -{ - int fd; - struct file *f; - int size; - - if (! copy_from_user (&fd, STACK_ADDR (sp,1))) { - *segfault = true; - return -1; - } - if ((f = process_get_file (fd)) == NULL) - return -1; - process_lock_filesys (); - size = inode_length (file_get_inode (f)); - process_unlock_filesys (); - return size; -} - -/* Read bytes from the file referenced by the given file - descriptor into the supplied user space buffer, returning - number of bytes read. */ -static int -syscall_read (void *sp, bool *segfault) -{ - int fd; - uint8_t *user_buffer; - size_t size, bytes_to_read; - - /* get arguments */ - if (! copy_from_user (&fd, STACK_ADDR (sp,1)) || - ! copy_from_user (&user_buffer, STACK_ADDR (sp, 2)) || - ! copy_from_user (&size, STACK_ADDR (sp,3))) { - *segfault = true; - return -1; - } - - /* ensure buffer is in user space */ - if (! is_user_vaddr (user_buffer) || - ! is_user_vaddr (user_buffer + size - 1)) { - *segfault = true; - return -1; - } - - bytes_to_read = size; - /* handle stdin */ - if (fd == STDIN_FILENO) { - char c; - while (bytes_to_read--) { - c = input_getc (); - if (! put_user (user_buffer++, c)) { - *segfault = true; - return -1; - } - } - return size; - } - /* get file */ - struct file *file = process_get_file (fd); - if (file == NULL) - return -1; - - char *kbuf = palloc_get_page (0); - if (kbuf == NULL) - return -1; - - /* read loop */ - do { - int bytes_read; - int blocksize = bytes_to_read; - if (bytes_to_read > PGSIZE) - blocksize = PGSIZE; - - /* read bytes */ - process_lock_filesys (); - bytes_read = file_read (file, kbuf, blocksize); - process_unlock_filesys (); - - /* Stop when EOF has been reached */ - if (bytes_read == 0) - break; - bytes_to_read -= bytes_read; - if (! memcpy_to_user (user_buffer, kbuf, bytes_read)) { - *segfault = true; - break; - } - user_buffer += bytes_read; - } while (bytes_to_read > 0); - - palloc_free_page (kbuf); - return size - bytes_to_read; -} - -/* Write bytes from user buffer into the specified - file, returning number of bytes written. */ -static int -syscall_write (void *sp, bool *segfault) -{ - int fd; - size_t size, bytes_to_write; - char *user_buffer; - - /* get arguments */ - if (! copy_from_user (&fd, STACK_ADDR (sp,1)) || - ! copy_from_user (&user_buffer, STACK_ADDR (sp, 2)) || - ! copy_from_user (&size, STACK_ADDR (sp,3))) { - *segfault = true; - return -1; - } - - /* ensure buffer is in user space */ - if (! is_user_vaddr (user_buffer) || - ! is_user_vaddr (user_buffer + size - 1)) { - *segfault = true; - return -1; - } - - /* get file handle */ - struct file *file = NULL; - if (fd != STDOUT_FILENO) { - file = process_get_file (fd); - if (file == NULL) - return -1; - } - - /* allocate kernel buffer */ - char *kbuf = palloc_get_page (0); - if (kbuf == NULL) - return -1; - - /* write loop */ - bytes_to_write = size; - do { - int blocksize = bytes_to_write; - if (bytes_to_write > PGSIZE) - blocksize = PGSIZE; - if (memcpy_from_user (kbuf, user_buffer, blocksize) == NULL) { - *segfault = true; - break; - } - if (fd == STDOUT_FILENO) { - putbuf (kbuf, blocksize); - bytes_to_write -= blocksize; - } else { - int bytes_written = 0; - int bytes_left_filesys = blocksize; - - process_lock_filesys (); - while (bytes_left_filesys > 0) { - bytes_written = file_write (file, kbuf, bytes_left_filesys); - if (bytes_written <= 0) { - break; - } - bytes_left_filesys -= bytes_written; - } - process_unlock_filesys (); - - if (bytes_written <= 0) - break; - bytes_to_write -= blocksize; - } - user_buffer += blocksize; - } while (bytes_to_write > 0); - - /* return bytes written */ - palloc_free_page (kbuf); - return size - bytes_to_write; -} - -/* Change the position where the next byte will be read or written */ -static int -syscall_seek (void *sp, bool *segfault) -{ - int fd; - off_t new_pos; - - /* get arguments */ - if (! copy_from_user (&fd, STACK_ADDR (sp,1)) || - ! copy_from_user (&new_pos, STACK_ADDR (sp, 2))) { - *segfault = true; - return 0; - } - - /* no way to return something sensible (void function) */ - struct file *file = process_get_file (fd); - if (file == NULL) - return 0; - - process_lock_filesys (); - file_seek (file, new_pos); - process_unlock_filesys (); - return 0; -} - -/* Returns the position of the next byte to be read or written */ -static int -syscall_tell (void *sp, bool *segfault) -{ - int fd; - unsigned r = 0; - - /* get arguments */ - if (! copy_from_user (&fd, STACK_ADDR (sp,1))) { - *segfault = true; - return 0; - } - - /* no way to return something sensible function */ - struct file *file = process_get_file (fd); - if (file == NULL) - return 0; - - process_lock_filesys (); - r = file_tell (file); - process_unlock_filesys (); - return r; -} - -/* Close the given file */ -static int -syscall_close (void *sp, bool *segfault) -{ - int fd; - - /* get arguments */ - if (! copy_from_user (&fd, STACK_ADDR (sp,1))) { - *segfault = true; - return 0; - } - - /* no way to return something sensible function (void) */ - (void) process_close_file (fd); - return 0; -} -- cgit v1.2.3