Exemplo n.º 1
0
Arquivo: undbx.c Projeto: dabble/undbx
static dbx_save_status_t _maybe_save_message(dbx_t *dbx, int imessage, char *dir, int force)
{
  dbx_save_status_t status = DBX_SAVE_NOOP;
  dbx_info_t *info = dbx->info + imessage;
  unsigned long long int size = 0;
  unsigned int message_size = 0;
  char *message = NULL;

  if (!force) 
    size = sys_filesize(dir, info->filename);
  
  if (force || (info->valid & DBX_MASK_MSGSIZE) == 0 || size != info->message_size) {
    message = dbx_message(dbx, imessage, &message_size);
    if (force || (size != message_size)) {
      status = _save_message(dir, info->filename, message, message_size);
      switch (status) {
      case DBX_SAVE_ERROR:
        dbx_progress_update(dbx->progress_handle, DBX_STATUS_ERROR, imessage, "%s", info->filename);
        break;
      case DBX_SAVE_OK:
        _set_message_filetime(info, dir);
        dbx_progress_update(dbx->progress_handle, DBX_STATUS_OK, imessage, "%s", info->filename);
        break;
      default:
        break;
      }
    }
    free(message);
  }

  return status;
}
Exemplo n.º 2
0
void sys_seek(int fd, unsigned position)
{
    struct file* file = map_find(get_filemap(), fd);

    if (file != NULL && position <= (unsigned)sys_filesize(fd))
        file_seek(file, position);
}
Exemplo n.º 3
0
static void
syscall_handler (struct intr_frame *f)
{
  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.
  memread_user(f->esp, &syscall_number, sizeof(syscall_number));
  _DEBUG_PRINTF ("[DEBUG] system call, number = %d!\n", syscall_number);

  // Store the esp, which is needed in the page fault handler.
  // refer to exception.c:page_fault() (see manual 4.3.3)
  thread_current()->current_esp = f->esp;

  // Dispatch w.r.t system call number
  // SYS_*** constants are defined in syscall-nr.h
  switch (syscall_number) {
  case SYS_HALT: // 0
    {
      sys_halt();
      NOT_REACHED();
      break;
    }

  case SYS_EXIT: // 1
    {
      int exitcode;
      memread_user(f->esp + 4, &exitcode, sizeof(exitcode));

      sys_exit(exitcode);
      NOT_REACHED();
      break;
    }

  case SYS_EXEC: // 2
    {
      void* cmdline;
      memread_user(f->esp + 4, &cmdline, sizeof(cmdline));

      int return_code = sys_exec((const char*) cmdline);
      f->eax = (uint32_t) return_code;
      break;
    }

  case SYS_WAIT: // 3
    {
      pid_t pid;
      memread_user(f->esp + 4, &pid, sizeof(pid_t));

      int ret = sys_wait(pid);
      f->eax = (uint32_t) ret;
      break;
    }

  case SYS_CREATE: // 4
    {
      const char* filename;
      unsigned initial_size;
      bool return_code;

      memread_user(f->esp + 4, &filename, sizeof(filename));
      memread_user(f->esp + 8, &initial_size, sizeof(initial_size));

      return_code = sys_create(filename, initial_size);
      f->eax = return_code;
      break;
    }

  case SYS_REMOVE: // 5
    {
      const char* filename;
      bool return_code;

      memread_user(f->esp + 4, &filename, sizeof(filename));

      return_code = sys_remove(filename);
      f->eax = return_code;
      break;
    }

  case SYS_OPEN: // 6
    {
      const char* filename;
      int return_code;

      memread_user(f->esp + 4, &filename, sizeof(filename));

      return_code = sys_open(filename);
      f->eax = return_code;
      break;
    }

  case SYS_FILESIZE: // 7
    {
      int fd, return_code;
      memread_user(f->esp + 4, &fd, sizeof(fd));

      return_code = sys_filesize(fd);
      f->eax = return_code;
      break;
    }

  case SYS_READ: // 8
    {
      int fd, return_code;
      void *buffer;
      unsigned size;

      memread_user(f->esp + 4, &fd, sizeof(fd));
      memread_user(f->esp + 8, &buffer, sizeof(buffer));
      memread_user(f->esp + 12, &size, sizeof(size));

      return_code = sys_read(fd, buffer, size);
      f->eax = (uint32_t) return_code;
      break;
    }

  case SYS_WRITE: // 9
    {
      int fd, return_code;
      const void *buffer;
      unsigned size;

      memread_user(f->esp + 4, &fd, sizeof(fd));
      memread_user(f->esp + 8, &buffer, sizeof(buffer));
      memread_user(f->esp + 12, &size, sizeof(size));

      return_code = sys_write(fd, buffer, size);
      f->eax = (uint32_t) return_code;
      break;
    }

  case SYS_SEEK: // 10
    {
      int fd;
      unsigned position;

      memread_user(f->esp + 4, &fd, sizeof(fd));
      memread_user(f->esp + 8, &position, sizeof(position));

      sys_seek(fd, position);
      break;
    }

  case SYS_TELL: // 11
    {
      int fd;
      unsigned return_code;

      memread_user(f->esp + 4, &fd, sizeof(fd));

      return_code = sys_tell(fd);
      f->eax = (uint32_t) return_code;
      break;
    }

  case SYS_CLOSE: // 12
    {
      int fd;
      memread_user(f->esp + 4, &fd, sizeof(fd));

      sys_close(fd);
      break;
    }

#ifdef VM
  case SYS_MMAP: // 13
    {
      int fd;
      void *addr;
      memread_user(f->esp + 4, &fd, sizeof(fd));
      memread_user(f->esp + 8, &addr, sizeof(addr));

      mmapid_t ret = sys_mmap (fd, addr);
      f->eax = ret;
      break;
    }

  case SYS_MUNMAP: // 14
    {
      mmapid_t mid;
      memread_user(f->esp + 4, &mid, sizeof(mid));

      sys_munmap(mid);
      break;
    }
#endif
#ifdef FILESYS
  case SYS_CHDIR: // 15
    {
      const char* filename;
      int return_code;

      memread_user(f->esp + 4, &filename, sizeof(filename));

      return_code = sys_chdir(filename);
      f->eax = return_code;
      break;
    }

  case SYS_MKDIR: // 16
    {
      const char* filename;
      int return_code;

      memread_user(f->esp + 4, &filename, sizeof(filename));

      return_code = sys_mkdir(filename);
      f->eax = return_code;
      break;
    }

  case SYS_READDIR: // 17
    {
      int fd;
      char *name;
      int return_code;

      memread_user(f->esp + 4, &fd, sizeof(fd));
      memread_user(f->esp + 8, &name, sizeof(name));

      return_code = sys_readdir(fd, name);
      f->eax = return_code;
      break;
    }

  case SYS_ISDIR: // 18
    {
      int fd;
      int return_code;

      memread_user(f->esp + 4, &fd, sizeof(fd));
      return_code = sys_isdir(fd);
      f->eax = return_code;
      break;
    }

  case SYS_INUMBER: // 19
    {
      int fd;
      int return_code;

      memread_user(f->esp + 4, &fd, sizeof(fd));
      return_code = sys_inumber(fd);
      f->eax = return_code;
      break;
    }

#endif


  /* unhandled case */
  default:
    printf("[ERROR] system call %d is unimplemented!\n", syscall_number);

    // ensure that waiting (parent) process should wake up and terminate.
    sys_exit(-1);
    break;
  }

}
Exemplo n.º 4
0
static void
syscall_handler (struct intr_frame *f) 
{
  if(f)
  {
    stack_address_check(f->esp);
    
    // get sys call number off the stack
    int sys_call_no = get_nth_arg_int(f->esp, 0);

    DPRINTF("system call! %d\n", sys_call_no);
    switch(sys_call_no)
    {
      case SYS_HALT:
        power_off();
        break;
      case SYS_EXIT:
        {
          int status = get_nth_arg_int(f->esp, 1);
          thread_current()->exit_status = status;
          process_terminate();
          return;
        }
        break;
      case SYS_EXEC:
        {
          char* file_name = (char*)get_nth_arg_ptr(f->esp, 1);
          user_string_add_range_check_and_terminate(file_name); 
          int tid = sys_exec(file_name);
          DPRINTF("exec %s, tid = %d\n", file_name, tid);
          f->eax = tid;
        }
        return;
      case SYS_WAIT:
        {
          int pid = get_nth_arg_int(f->esp, 1);
          int ret = process_wait(pid);
          DPRINTF("wait for pid %d by %d return %d\n", pid, thread_current()->tid ,ret);
          f->eax = ret;
        }
        return;
      case SYS_CREATE:
        {
          char* file_name = (char*)get_nth_arg_ptr(f->esp, 1); 
          user_string_add_range_check_and_terminate(file_name);
          int size = get_nth_arg_int(f->esp, 2);
          DPRINTF("sys_create(%s,%d)\n", file_name, size);
          f->eax = sys_create(file_name, size);
        }
        return;
      case SYS_REMOVE:
        {
          char* file_name = (char*)get_nth_arg_ptr(f->esp, 1); 
          user_string_add_range_check_and_terminate(file_name); 
          DPRINTF("sys_remove(%s)\n", file_name);
          f->eax = sys_remove(file_name);
        }
        return;
      case SYS_OPEN:
        {
          char* file_name = (char*)get_nth_arg_ptr(f->esp, 1); 
          user_string_add_range_check_and_terminate(file_name); 
          DPRINTF("sys_open(%s)\n", file_name);
          f->eax = sys_open(file_name);
        }
        return; 
      case SYS_FILESIZE:
        {
          int fd = get_nth_arg_int(f->esp, 1);
          DPRINTF("sys_filesize(%d)\n", fd);
          f->eax = sys_filesize(fd);
        }
        return;
      case SYS_READ:
        {
          int fd = get_nth_arg_int(f->esp, 1);
          char* buf = (char*)get_nth_arg_ptr(f->esp, 2); 
          int size = get_nth_arg_int(f->esp, 3);
          user_add_range_check_and_terminate(buf, size);
          DPRINTF("sys_read(%d,%s,%d)\n", fd, buf, size);
          f->eax = sys_read(fd, buf, size);
        }
        return;
      case SYS_WRITE:
        {
          int fd = get_nth_arg_int(f->esp, 1);
          char* buf = (char*)get_nth_arg_ptr(f->esp, 2); 
          int size = get_nth_arg_int(f->esp, 3);
          user_add_range_check_and_terminate(buf, size);
          DPRINTF("sys_write(%d,%s,%d)\n", fd, buf, size);
          f->eax = sys_write(fd, buf, size);
        }
        return;
      case SYS_SEEK:
        {
          int fd = get_nth_arg_int(f->esp, 1);
          unsigned pos = get_nth_arg_int(f->esp, 2);
          DPRINTF("sys_seek(%d,%d)\n", fd, pos);
          sys_seek(fd, pos);
        }
        return;
      case SYS_TELL:
        {
          int fd = get_nth_arg_int(f->esp, 1);
          DPRINTF("sys_tell(%d)\n", fd);
          f->eax = sys_tell(fd);
        }
        return;
      case SYS_CLOSE:
        {
          int fd = get_nth_arg_int(f->esp, 1);
          DPRINTF("sys_close(%d)\n", fd);
          sys_close(fd);
        }
        return;
        /*
      case SYS_MMAP:
      case SYS_MUNMAP:
      case SYS_CHDIR:
      case SYS_MKDIR:
      case SYS_READDIR:
      case SYS_ISDIR:
      case SYS_INUMBER:
      */
      default:
        thread_exit();
        break;
    }
  }
  else
    thread_exit();
}
Exemplo n.º 5
0
static void
syscall_handler (struct intr_frame *f) 
{
  int sys_vector;
  sys_vector=*(int *)(f->esp);
  switch(sys_vector)
  {
  case SYS_HALT:
    esp_under_phys_base(f, 0);
    sys_halt ();
    break;
  case SYS_EXIT:
    if ((void *)((int *)f->esp + 1) >= PHYS_BASE)
      sys_exit (-1);
    else
      sys_exit (*((int *)f->esp + 1));
    break;
  case SYS_EXEC:
    esp_under_phys_base(f, 1);
    under_phys_base (*((int **)f->esp + 1));
    sys_exec (*((int **)f->esp + 1), f);
    break;
  case SYS_WAIT:
    esp_under_phys_base(f, 1);
    sys_wait (*((int *)f->esp + 1), f);
    break;
  case SYS_CREATE:
    if ((void*)*((int **)f->esp + 1) == NULL)
      sys_exit(-1);
    esp_under_phys_base(f, 2);
    under_phys_base (*((int **)f->esp + 1));
    sys_create (*((int **)f->esp + 1), *((int *)f->esp + 2), f);
    break;
  case SYS_REMOVE:
    esp_under_phys_base(f, 1);
    under_phys_base (*((int **)f->esp + 1));
    sys_remove (*((int **)f->esp + 1), f);
    break;
  case SYS_OPEN:
    if ((void*)*((int **)f->esp + 1) == NULL)
      sys_exit(-1);
    esp_under_phys_base(f, 1);
    under_phys_base (*((int **)f->esp + 1));
    sys_open (*((int **)f->esp + 1), f);
    break;
  case SYS_FILESIZE:
    esp_under_phys_base(f, 1);
    check_fd(*((int *)f->esp + 1), -1, f);
    sys_filesize (*((int *)f->esp + 1), f);
    break;
  case SYS_READ:
    esp_under_phys_base(f, 3);
    under_phys_base (*((int **)f->esp + 2));
    check_fd(*((int *)f->esp + 1), -1, f)
    sys_read (*((int *)f->esp + 1), *((int **)f->esp + 2), *((int *)f->esp + 3), f);
    break;
  case SYS_WRITE:
    esp_under_phys_base(f, 3);
    under_phys_base (*((int **)f->esp + 2));
    check_fd(*((int *)f->esp + 1), -1, f)
    sys_write (*((int *)f->esp + 1), *((int **)f->esp + 2), *((int *)f->esp + 3), f);
    break;
  case SYS_SEEK:
    esp_under_phys_base(f, 2);
    check_fd(*((int *)f->esp + 1), 0, f)
    sys_seek (*((int *)f->esp + 1), *((int *)f->esp + 2), f);
    break;
  case SYS_TELL:
    esp_under_phys_base(f, 1);
    check_fd(*((int *)f->esp + 1), 0, f)
    sys_tell (*((int *)f->esp + 1), f);
    break;
  case SYS_CLOSE:
    esp_under_phys_base(f, 1);
    check_fd(*((int *)f->esp + 1), 0, f)
    sys_close (*((int *)f->esp + 1), f);
    break;
  }
}
Exemplo n.º 6
0
/* Syscall handler calls the appropriate function. */
static void
syscall_handler (struct intr_frame *f) 
{
  int ret = 0;
  int *syscall_nr = (int *) f->esp;
  void *arg1 = (int *) f->esp + 1;
  void *arg2 = (int *) f->esp + 2;
  void *arg3 = (int *) f->esp + 3;

  /* Check validate pointer. */
  if (!is_user_vaddr (syscall_nr) || !is_user_vaddr (arg1) ||
      !is_user_vaddr (arg2)       || !is_user_vaddr (arg3))
    sys_exit (-1);
  
  switch (*syscall_nr)
    {
    case SYS_HALT:
      sys_halt ();
      break;
    case SYS_EXIT:
      sys_exit (*(int *) arg1);
      break;
    case SYS_EXEC:
      ret = sys_exec (*(char **) arg1);
      break;
    case SYS_WAIT:
      ret = sys_wait (*(pid_t *) arg1);
      break;
    case SYS_CREATE:
      ret = sys_create (*(char **) arg1, *(unsigned *) arg2);
      break;
    case SYS_REMOVE:
      ret = sys_remove (*(char **) arg1);
      break;
    case SYS_OPEN:
      ret = sys_open (*(char **) arg1);
      break;
    case SYS_FILESIZE:
      ret = sys_filesize (*(int *) arg1);
      break;
    case SYS_READ:
      ret = sys_read (*(int *) arg1, *(void **) arg2, *(unsigned *) arg3);
      break;
    case SYS_WRITE:
      ret = sys_write (*(int *) arg1, *(void **) arg2, *(unsigned *) arg3);
      break;
    case SYS_SEEK:
      sys_seek (*(int *) arg1, *(unsigned *) arg2);
      break;
    case SYS_TELL:
      ret = sys_tell (*(int *) arg1);
      break;
    case SYS_CLOSE:
      sys_close (*(int *) arg1);
      break;
    default:
      printf (" (%s) system call! (%d)\n", thread_name (), *syscall_nr);
      sys_exit (-1);
      break;
    }

  f->eax = ret;
}
Exemplo n.º 7
0
/* Maps the file open as FD into the process' virtual address space - entire
   file mapped into consecutive virtual pages starting at ADDR. (Lazy load
   pages in mmap regions). (Evicting a page mapped by mmap writes it back to
   the actual file it was mapped from). (Set spare bytes on final page to zero
   when that page is faulted in the file system, and ignore these bytes when
   page is written back to disk). Returns mapid_t for the mapping, or -1 on
   failure. Failure occurs when file has length 0, if addr is not page aligned,
   if range of pages mapped overlaps any existing mapped pages (including the
   stack or pages mapped at executable load time), if addr is 0, or if fd
   is 0 or 1. */
static mapid_t
sys_mmap(int fd, void *addr)
{
  /* Check that fd is a valid file descriptor. */
  check_fd(fd);

  /* Cannot map stdin or stdout. */
  if (fd == STDIN_FILENO || fd == STDOUT_FILENO) {
    return ERROR;
  }

  /* Address to map to cannot be 0, because some Pintos code assumes virtual
     page 0 is not mapped. */
  if (addr == 0) {
    return ERROR;
  }

  int size = sys_filesize(fd);

  /* Cannot map a file of size 0 bytes. */
  if (size == 0) {
    return ERROR;
  }

  /* ADDR must be page-aligned. */
  if (pg_ofs(addr) != 0) {
    return ERROR;
  }

  /* If ADDR is not in user/process address space, we cannot map
     the file there. */
  if (!is_user_vaddr(addr)) {
    sys_exit(ERROR);
  }

  /* Pages is number of pages needed to map file.
     (size % PGSIZE) gives the number of spare bytes on the final page.
     This is necessary because the division is integer division, and so
     will round down, but we want it to round up. */
  int pages = size / PGSIZE;
  if ((size % PGSIZE) != 0) {
    pages++;
  }

  struct thread *cur = thread_current();
  struct hash *mmap_table = &cur->mmap_table;
  struct hash *spt = &cur->supp_pt;

  lock_acquire(&secure_file);
  struct file *old_file = get_file(fd);
  if (!old_file) {
    lock_release(&secure_file);
    sys_exit(ERROR);
  }
  /* Must use file_reopen() to get independent 'struct file *' for same file
     (with same inode) because the file could be being read at different points
     (file->pos could be different) and they could have different
     file->deny_write (file_deny_write() could be called on one struct file but
     not another of same file (inode) but different struct file). */
  struct file *file = file_reopen(old_file);
  lock_release(&secure_file);

  int i;
  int bytes_to_write;
  void *cur_page;
  /* Check that the contiguous range of pages to be mapped doesn't overlap
     any existing set of mapped pages (Not including stack). Can then add
     these pages to the supplementary page table. */
  for (i = 0; i < pages; i++) {
    cur_page = (void *) ((uint8_t *) addr) + (i * PGSIZE);
    /* Check to see if there is an existing mapped page at what would be the
       i'th page of this mapped file. */
    if (get_spt_entry(spt, cur_page) != NULL) {
      return ERROR;
    }
    /* Only on the last page do we potentially not fill up whole page with
       part of file. */
    bytes_to_write = (i == (pages - 1)) ? (size % PGSIZE) : PGSIZE;
    /* Add current page to the supplementary page table. */
    spt_insert_file(cur_page, file, bytes_to_write,
                       PGSIZE - bytes_to_write, i * PGSIZE, true, true, false);
  }

  mapid_t mapid = cur->next_mapid;

  /* Lock must be acquired to call hash_insert() in mmap_table_insert(), and
     since we have thread_current() here already it makes sense to lock here
     rather than in mmap_table_insert() in mmap.c. */
  lock_acquire(&cur->mmap_table_lock);
  bool success = mmap_table_insert(mmap_table, addr, addr + size, pages,
                                     mapid, file);
  lock_release(&cur->mmap_table_lock);

  /* Return -1 if mmap_table_insert wasn't successful (meaning there isn't
     enough space to malloc for a struct mmap_mapping *). */
  if (!success) {
    return ERROR;
  }

  /* Increment next_mapid for this thread, so that the next mmap will have a
     different mapid, ensuring unique mapids for all mappings for a process.
     Increment after checking for mmap_table_insert() success status, because
     in the case of failure, we can reuse the mapid that the failed mapping
     would have had. */
  cur->next_mapid++;

  /* If successful, function returns the mapid that uniquely identifies
     the mapping within the process. */
  return mapid;
}
Exemplo n.º 8
0
static void
syscall_handler (struct intr_frame *f)
{
  /* Check to see that we can read supplied user memory pointer, using the
     check_mem_ptr helper() function, in get_word_from_stack(). If the
     check fails, the process is terminated. */

  int syscall_number = (int)get_word_on_stack(f, 0);

  switch(syscall_number) {
    case SYS_HALT:
    {
      sys_halt();
      break;
    }
    case SYS_EXIT:
    {
      int status = (int)get_word_on_stack(f, 1);
      sys_exit(status);
      /* Returns exit status to the kernel. */
      f->eax = status;
      break;
    }
    case SYS_EXEC:
    {
      const char *cmd_line  = (const char *)get_word_on_stack(f, 1);
      pid_t pid = sys_exec(cmd_line);
      /* Returns new processes pid. */
      f->eax = pid;
      break;
    }
    case SYS_WAIT:
    {
      pid_t pid = (pid_t)get_word_on_stack(f, 1);
      /* Returns child's exit status (pid argument is pid of this child). */
      f->eax = sys_wait(pid);
      break;
    }
    case SYS_CREATE:
    {
      const char *filename  = (const char *)get_word_on_stack(f, 1);
      unsigned initial_size = (unsigned)get_word_on_stack(f, 2);
      /* Returns true to the kernel if creation is successful. */
      f->eax = (int)sys_create(filename, initial_size);
      break;
    }
    case SYS_REMOVE:
    {
      const char *filename = (const char *)get_word_on_stack(f, 1);
      /* Returns true if successful, and false otherwise. */
      f->eax = sys_remove(filename);
      break;
    }
    case SYS_OPEN:
    {
      const char *filename = (const char *)get_word_on_stack(f, 1);
      /* Returns file descriptor of opened file, or -1 if it could not
         be opened. */
      f->eax = sys_open(filename);
      break;
    }
    case SYS_FILESIZE:
    {
      int fd = (int)get_word_on_stack(f, 1);
      /* Returns size of file in bytes. */
      f->eax = sys_filesize(fd);
      break;
    }
    case SYS_READ:
    {
      int fd        = (int)get_word_on_stack(f, 1);
      void *buffer  = (void *)get_word_on_stack(f, 2);
      unsigned size = (unsigned)get_word_on_stack(f, 3);
      /* Returns number of bytes actually read, or -1 if it could not
         be read. */
      f->eax = sys_read(fd, buffer, size, f);
      break;
    }
    case SYS_WRITE:
    {
      int fd        = (int)get_word_on_stack(f, 1);
      void *buffer  = (void *)get_word_on_stack(f, 2);
      unsigned size = (unsigned)get_word_on_stack(f, 3);
      /* Returns number of bytes written. */
      f->eax = sys_write(fd, buffer, size);
      break;
    }
    case SYS_SEEK:
    {
      int fd             = (int)get_word_on_stack(f, 1);
      unsigned position  = (int)get_word_on_stack(f, 2);
      sys_seek(fd, position);
      break;
    }
    case SYS_TELL:
    {
      int fd        = (int)get_word_on_stack(f, 1);
      /* Returns the position of the next byte to be read or written in open
         file 'fd' (in bytes, from start of file). */
      f->eax = sys_tell(fd);
      break;
    }
    case SYS_CLOSE:
    {
      int fd        = (int)get_word_on_stack(f, 1);
      sys_close(fd);
      break;
    }
    case SYS_MMAP:
    {
        int fd     = (int)get_word_on_stack(f, 1);
        void *addr = (void *)get_word_on_stack(f, 2);
        f->eax = sys_mmap(fd, addr);
        break;
    }
    case SYS_MUNMAP:
    {
        mapid_t mapping = (mapid_t)get_word_on_stack(f, 1);
        sys_munmap(mapping);
        break;
    }
    default:
    {
      NOT_REACHED();
    }
  }

}
Exemplo n.º 9
0
static void
syscall_handler (struct intr_frame *f) 
{
  int *sys_call;

  int *status;

  int *fd;
  const char **buf;
  int *size;

  const char **file;

  tid_t *pid;

  const char **cmd_line;

  unsigned *initial_size;

  unsigned *position;

  void **buffer;

  sys_call = (int*) f->esp;
  check_ptr(sys_call);

  switch(*sys_call) {
  case SYS_HALT:
    sys_halt ();
    break;
  case SYS_EXIT:
    status = (int *) get_arg_ptr (f->esp, 1);
    sys_exit(*status);
    NOT_REACHED();
    break;
  case SYS_EXEC:
    cmd_line = (const char **) get_arg_ptr (f->esp, 1);
    f->eax = sys_exec (*cmd_line);
    break;
  case SYS_WAIT:
    pid = (tid_t *) get_arg_ptr (f->esp, 1);
    f->eax = sys_wait (*pid);
    break;
  case SYS_CREATE:
    file = (const char **) get_arg_ptr (f->esp, 1);
    initial_size = (unsigned *) get_arg_ptr (f->esp, 2);
    f->eax = sys_create (*file, *initial_size);
    break;
  case SYS_REMOVE:
    file = (const char **) get_arg_ptr (f->esp, 1);
    f->eax = sys_remove (*file);
    break;
  case SYS_OPEN:
    file = (const char **) get_arg_ptr(f->esp, 1);
    f->eax = sys_open (*file);
    break;
  case SYS_FILESIZE:
    fd = (int *) get_arg_ptr (f->esp, 1);
    f->eax = sys_filesize (*fd);
    break;
  case SYS_READ:
    fd = (int *) get_arg_ptr (f->esp, 1);
    buffer = (void **) get_arg_ptr (f->esp, 2);
    size = (int *) get_arg_ptr (f->esp, 3);
    f->eax = sys_read (*fd, *buffer, *size);
    break;
  case SYS_WRITE:
    fd = (int *) get_arg_ptr (f->esp, 1);
    buf = (const void **) get_arg_ptr (f->esp, 2);
    size = (int *) get_arg_ptr (f->esp, 3);
    f->eax = sys_write (*fd, *buf, *size);
    break;
  case SYS_SEEK:
    fd = (int *) get_arg_ptr (f->esp, 1);
    position = (unsigned *) get_arg_ptr (f->esp, 2);
    sys_seek (*fd, *position);
    break;
  case SYS_TELL:
    fd = (int *) get_arg_ptr (f->esp, 1);
    f->eax = sys_tell (*fd);
    break;
  case SYS_CLOSE:
    fd = (int *) get_arg_ptr (f->esp, 1);
    sys_close (*fd);
    break;
  default:
    printf ("Unrecognized system call!\n");
    thread_exit ();
  }
}