Exemple #1
0
int main() {
  usr_sem_t *wait0, *wait1, *read_write_lock;
  uint32_t prog0, prog1;
  int ret0, ret1;

  puts("Create the semaphores.\n");
  wait0 = syscall_sem_open("wait0", 0);
  wait1 = syscall_sem_open("wait1", 0);
  read_write_lock = syscall_sem_open("rwlock", 1);
  read_write_lock = read_write_lock;

  puts("Run the children.\n");
  prog0 = syscall_exec(VOLUME "sem_barrier_p0");
  prog1 = syscall_exec(VOLUME "sem_barrier_p1");

  puts("Wait for them to finish.\n");
  ret0 = syscall_join(prog0);
  ret1 = syscall_join(prog1);
  printf("Children joined with return values %d and %d.\n", ret0, ret1);

  puts("Destroy the semaphores.\n");
  syscall_sem_destroy(wait0);
  syscall_sem_destroy(wait1);

  syscall_halt();
  return 0;
}
Exemple #2
0
int main(void)
{
  uint32_t child;
  uint32_t child2;
  uint32_t child3;
  uint32_t child4;
  int ret;
  int ret2;
  int ret3;
  int ret4;
  int i;
for(i = 0; i < 10;i++) {
  printf("Starting program %s\n", prog);
  child = syscall_exec(prog);
  child2 = syscall_exec(prog);
  child3 = syscall_exec(prog);
  child4 = syscall_exec(prog);
  printf("Now joining child %d\n", child);
  
  ret = (char)syscall_join(child);
  ret2 = (char)syscall_join(child2);
  ret3 = (char)syscall_join(child3);
  ret4 = (char)syscall_join(child4);
  printf("Child joined with status: %d\n", ret);
  printf("Child joined with status: %d\n", ret2);
  printf("Child joined with status: %d\n", ret3);
  printf("Child joined with status: %d\n", ret4);
   }
  syscall_halt();
  return 0;
}
Exemple #3
0
int main(void)
{
  int i;
  char str[3];

  syscall_write(1, "Validprogram1: Caling 'vallidprogram2'\n",39);
  
  syscall_exec(syscall_exec(validprog));

  syscall_write(1,"That is it! Goodbye\n",20);
  syscall_exit(4);
  return 0;
}
Exemple #4
0
int main(void)
{
  int a,b,c,d,e;
  a = syscall_exec("[arkimedes]a", -1);
  b = syscall_exec("[arkimedes]b", 9000);
  c = syscall_exec("[arkimedes]c", 3000);
  d = syscall_exec("[arkimedes]d", 4000);
  e = syscall_exec("[arkimedes]e", 2000);
  syscall_join(a);
  syscall_join(b);
  syscall_join(c);
  syscall_join(d);
  syscall_join(e);
  return 0;
}
Exemple #5
0
void do_syscall(TrapFrame *tf) {
   int id = tf->eax;
   switch(id) {
      case SYS_fork:  syscall_fork(tf); break;
      case SYS_exec:  syscall_exec(tf); break;
      case SYS_exit:  syscall_exit(tf); break;
      case SYS_getpid:  syscall_getpid(tf); break;
      case SYS_waitpid:  syscall_waitpid(tf); break;
      case SYS_puts1:  printk((char*)(tf->ebx)); printk("   %d\n", current->pid); break;
      case SYS_puts: syscall_puts(tf); break;
      case SYS_read_line: syscall_read_line(tf); break;
      case SYS_sleep: syscall_sleep(tf); break;

      case SYS_open: syscall_open(tf); break;
      case SYS_read: syscall_read(tf); break;
      case SYS_write: syscall_write(tf); break;
      case SYS_create: syscall_create(tf); break;
      case SYS_close: syscall_close(tf); break;
      case SYS_delete: syscall_delete(tf); break;
      case SYS_lseek: syscall_lseek(tf); break;
      case SYS_dup: syscall_dup(tf); break;
      case SYS_dup2: syscall_dup2(tf); break;
      case SYS_mkdir: syscall_mkdir(tf); break;
      case SYS_rmdir: syscall_rmdir(tf); break;
      case SYS_lsdir: syscall_lsdir(tf); break;
      case SYS_chdir: syscall_chdir(tf); break;
      //default: panic("Unknown system call type");
   }
}
Exemple #6
0
int cmd_run(char* prog) {
  if (does_file_exist(prog)) {
    return syscall_join(syscall_exec(prog));
  } else {
    printf("No such program: %s.\n", prog);
    return 1;
  }
}
Exemple #7
0
int main(void)
{
  uint32_t child;
  int ret;
  printf("Starting program %s\n", prog);
  child = syscall_exec(prog);
  printf("Now joining child %d\n", child);
  ret = (char)syscall_join(child);
  printf("Child joined with status: %d\n", ret);
  
  printf("Starting program %s\n", prog2);
  child = syscall_exec(prog2);
  printf("Now joining child %d\n", child);
  ret = (char)syscall_join(child);
  printf("Child joined with status: %d\n", ret);
  syscall_halt();
  return 0;
}
Exemple #8
0
int main(void) {
    uint32_t child;
    printf("Beginning proc_test \n");
    child = syscall_exec(prog);
    syscall_join(child);
    printf("Ending proc_test \n");
    syscall_halt();
    return 0;
}
Exemple #9
0
int main(void)
{
    int child_p, retval;

    write("dette er en test\n");

    child_p = syscall_exec("[test]testexit");
    retval = syscall_join(child_p);

    syscall_halt();

    return -1;
}
Exemple #10
0
int background_run(char* prog) {
  if (background_proc != -1) {
    printf("Error: Can only run one background process at a time.\n");
    printf("Use 'wait' to block until it stops.\n");
    return 1;
  } else {
    if (does_file_exist(prog)) {
      background_proc = syscall_exec(prog);
      printf("Background process spawned with PID %d\n", background_proc);
      return 0;
    } else {
      printf("No such program: %s.\n", prog);
      return 1;
    }
  }
}
Exemple #11
0
/*
 * get system call
 */
static void
syscall_handler (struct intr_frame *f)
{
  int *esp = (int *)syscall_user_to_kernel_vaddr(f->esp);
  switch(*esp)
  {
    case SYS_WRITE:
      syscall_write(f);
      break;
    case SYS_EXIT:
      syscall_exit(f);
      break;
    case SYS_HALT:
      syscall_halt(f);
      break;
    case SYS_EXEC:
      syscall_exec(f);
      break;
    case SYS_CREATE:
      syscall_create(f);
      break;
    case SYS_REMOVE:
      syscall_remove(f);
      break;
    case SYS_OPEN:
      syscall_open(f);
      break;
    case SYS_FILESIZE:
      syscall_filesize(f);
      break;
    case SYS_READ:
      syscall_read(f);
      break;
    case SYS_SEEK:
      syscall_seek(f);
      break;
    case SYS_TELL:
      syscall_tell(f);
      break;
    case SYS_CLOSE:
      syscall_close(f);
      break;
    case SYS_WAIT:
      syscall_wait(f);
      break;
  }
}
Exemple #12
0
/**
 * Handle system calls. Interrupts are enabled when this function is
 * called.
 *
 * @param user_context The userland context (CPU registers as they
 * where when system call instruction was called in userland)
 */
void syscall_handle(context_t *user_context)
{
    /* When a syscall is executed in userland, register a0 contains
     * the number of the syscall. Registers a1, a2 and a3 contain the
     * arguments of the syscall. The userland code expects that after
     * returning from the syscall instruction the return value of the
     * syscall is found in register v0. Before entering this function
     * the userland context has been saved to user_context and after
     * returning from this function the userland context will be
     * restored from user_context.
     */
    switch(user_context->cpu_regs[MIPS_REGISTER_A0]) {
    case SYSCALL_HALT:
        halt_kernel();
        break;
    case SYSCALL_READ:
        user_context->cpu_regs[MIPS_REGISTER_V0] =
            syscall_read(user_context->cpu_regs[MIPS_REGISTER_A1],
                         (void *)user_context->cpu_regs[MIPS_REGISTER_A2],
                         user_context->cpu_regs[MIPS_REGISTER_A3]);
        break;
    case SYSCALL_WRITE:
        user_context->cpu_regs[MIPS_REGISTER_V0] =
            syscall_write(user_context->cpu_regs[MIPS_REGISTER_A1],
                          (const void *)user_context->cpu_regs[MIPS_REGISTER_A2],
                          user_context->cpu_regs[MIPS_REGISTER_A3]);
        break;
    case SYSCALL_EXEC:
        user_context->cpu_regs[MIPS_REGISTER_V0] =
            syscall_exec((const char *)user_context->cpu_regs[MIPS_REGISTER_A1]);
        break;
    case SYSCALL_EXIT:
        syscall_exit(user_context->cpu_regs[MIPS_REGISTER_A1]);
        break;
    case SYSCALL_JOIN:
        user_context->cpu_regs[MIPS_REGISTER_V0] =
            syscall_join(user_context->cpu_regs[MIPS_REGISTER_A1]);
        break;
    default: 
        KERNEL_PANIC("Unhandled system call\n");
    }

    /* Move to next instruction after system call */
    user_context->pc += 4;
}
Exemple #13
0
/**
 * Handle system calls. Interrupts are enabled when this function is
 * called.
 *
 * @param user_context The userland context (CPU registers as they
 * where when system call instruction was called in userland)
 */
void syscall_handle(context_t *user_context)
{
  /* When a syscall is executed in userland, register a0 contains
   * the number of the syscall. Registers a1, a2 and a3 contain the
   * arguments of the syscall. The userland code expects that after
   * returning from the syscall instruction the return value of the
   * syscall is found in register v0. Before entering this function
   * the userland context has been saved to user_context and after
   * returning from this function the userland context will be
   * restored from user_context.
   */
  switch (A0)
  {
  case SYSCALL_HALT:
    halt_kernel();
    break;
  case SYSCALL_READ:
    V0 = tty_read((int) A1, (void*) A2, (int) A3);
    break;
  case SYSCALL_WRITE:
    V0 = tty_write((int) A1, (void*) A2, (int) A3);
    break;
  case SYSCALL_EXEC:
    V0 = syscall_exec((char*) A1);
    break;
  case SYSCALL_EXIT:
    syscall_exit((int) A1);
    break;
  case SYSCALL_JOIN:
    V0 = syscall_join((process_id_t) A1);
    break;
  case SYSCALL_MEMLIMIT:
    V0 = (int)process_memlimit((void *) A1);
    break;
  default:
    KERNEL_PANIC("Unhandled system call\n");
  }

  /* Move to next instruction after system call */
  user_context->pc += 4;
}
Exemple #14
0
void syscall(struct _irq_regs *r)
{
	int service = r->rax & 0xff;

	switch (service) {
	case printf:
		r->rax = syscall_printf((char *)(r->rsi), (void *)r->rdi);
	break;
	case getchar:
		r->rax = syscall_getchar();
	break;
	case puts:
		r->rax = syscall_puts((char*)r->rsi);
	break;
	case getcwd:
		r->rax = syscall_getcwd((char *)r->rdi, (size_t)r->rcx);
	break;
	case opendir:
		r->rax = syscall_opendir((char *)r->rsi);
	break;
	case read_dirent_entry:
		r->rsi = syscall_read_dirent_entry(r->rsi, (char*)r->rdi,
						   (unsigned long*)r->rcx);
	break;
	case get_file_info:
		r->rax = syscall_get_file_info((char*)r->rsi);
	break;
	case chdir:
		r->rax = syscall_chdir((char*)r->rsi);
	break;
	case exec:
		r->rax = syscall_exec((char*)r->rdi);
	break;
	default:
		kprintf("int 80, bad service, %d\r\n", service);
	break;
	}
}
Exemple #15
0
/**
 * Handle system calls. Interrupts are enabled when this function is
 * called.
 *
 * @param user_context The userland context (CPU registers as they
 * where when system call instruction was called in userland)
 */
void syscall_handle(context_t *user_context)
{
  /* When a syscall is executed in userland, register a0 contains
   * the number of the syscall. Registers a1, a2 and a3 contain the
   * arguments of the syscall. The userland code expects that after
   * returning from the syscall instruction the return value of the
   * syscall is found in register v0. Before entering this function
   * the userland context has been saved to user_context and after
   * returning from this function the userland context will be
   * restored from user_context.
   */
  switch (A0) {
  case SYSCALL_HALT:
    halt_kernel();
    break;
  case SYSCALL_READ: {
      int filehandle = (int)A1;
      if (filehandle == FILEHANDLE_STDIN || filehandle == FILEHANDLE_STDOUT
        || filehandle == FILEHANDLE_STDERR) {
        V0 = io_read((int) A1, (void*) A2, (int) A3);
      } else {
        V0 = syscall_read((openfile_t)A1, (void *)A2, (int)A3);
      }
    }
    break;
  case SYSCALL_WRITE: {
      int filehandle = (int)A1;
      if (filehandle == FILEHANDLE_STDIN || filehandle == FILEHANDLE_STDOUT
        || filehandle == FILEHANDLE_STDERR) {
        V0 = io_write((int) A1, (void*) A2, (int) A3);
      } else {
        V0 = syscall_write((openfile_t)A1, (void *)A2, (int)A3);
      }
    }
    break;
  case SYSCALL_EXEC:
    V0 = syscall_exec((char*) A1);
    break;
  case SYSCALL_EXIT:
    syscall_exit((int) A1);
    break;
  case SYSCALL_JOIN:
    V0 = syscall_join((process_id_t) A1);
    break;
  case SYSCALL_OPEN:
    V0 = syscall_open((char *) A1);
  break;
  case SYSCALL_CLOSE:
    V0 = syscall_close((openfile_t) A1);
  break;
  case SYSCALL_SEEK:
    V0 = syscall_seek((openfile_t)A1, (int)A2);
  break;
  case SYSCALL_CREATE:
    V0 = syscall_create((const char *)A1, (int)A2);
  break;
  case SYSCALL_REMOVE:
    V0 = syscall_remove((const char *)A1);
  break;
  case SYSCALL_TELL:
    V0 = syscall_tell((openfile_t)A1);
  break;
  case SYSCALL_SEM_OPEN:
    V0 = (uint32_t) usr_sem_open((char*) A1, A2);
    break;
  case SYSCALL_SEM_PROCURE:
    V0 = usr_sem_p((usr_sem_t*) A1);
    break;
  case SYSCALL_SEM_VACATE:
    V0 = usr_sem_v((usr_sem_t*) A1);
    break;
  case SYSCALL_SEM_DESTROY:
    V0 = usr_sem_destroy((usr_sem_t*) A1);
    break;
  default:
    KERNEL_PANIC("Unhandled system call\n");
  }

  /* Move to next instruction after system call */
  user_context->pc += 4;
}
Exemple #16
0
/**
 * Handle system calls. Interrupts are enabled when this function is
 * called.
 *
 * @param user_context The userland context (CPU registers as they
 * where when system call instruction was called in userland)
 */
void syscall_handle(context_t *user_context)
{
    /* When a syscall is executed in userland, register a0 contains
     * the number of the syscall. Registers a1, a2 and a3 contain the
     * arguments of the syscall. The userland code expects that after
     * returning from the syscall instruction the return value of the
     * syscall is found in register v0. Before entering this function
     * the userland context has been saved to user_context and after
     * returning from this function the userland context will be
     * restored from user_context.
     */
    switch(user_context->cpu_regs[MIPS_REGISTER_A0]) {
    case SYSCALL_HALT:
        halt_kernel();
        break;
    case SYSCALL_EXIT:
        syscall_exit(user_context->cpu_regs[MIPS_REGISTER_A1]);
        break;
    case SYSCALL_WRITE:
        user_context->cpu_regs[MIPS_REGISTER_V0] =
            syscall_write(user_context->cpu_regs[MIPS_REGISTER_A1],
                          (char*)user_context->cpu_regs[MIPS_REGISTER_A2],
                          (user_context->cpu_regs[MIPS_REGISTER_A3]));
        break;
    case SYSCALL_READ:
        user_context->cpu_regs[MIPS_REGISTER_V0] =
            syscall_read(user_context->cpu_regs[MIPS_REGISTER_A1],
                         (char*)user_context->cpu_regs[MIPS_REGISTER_A2],
                         (user_context->cpu_regs[MIPS_REGISTER_A3]));
        break;
    case SYSCALL_JOIN:
        user_context->cpu_regs[MIPS_REGISTER_V0] =
          syscall_join(user_context->cpu_regs[MIPS_REGISTER_A1]);
        break;
    case SYSCALL_EXEC:
        user_context->cpu_regs[MIPS_REGISTER_V0] =
            syscall_exec((char*)user_context->cpu_regs[MIPS_REGISTER_A1]);
        break;
    case SYSCALL_FORK:
        user_context->cpu_regs[MIPS_REGISTER_V0] =
            syscall_fork((void (*)(int))user_context->cpu_regs[MIPS_REGISTER_A1],
                         user_context->cpu_regs[MIPS_REGISTER_A2]);
        break;
    case SYSCALL_LOCK_CREATE:
        user_context->cpu_regs[MIPS_REGISTER_V0] =
            syscall_lock_create((lock_t*) user_context->cpu_regs[MIPS_REGISTER_A1]);
        break;
    case SYSCALL_LOCK_ACQUIRE:
        syscall_lock_acquire((lock_t*) user_context->cpu_regs[MIPS_REGISTER_A1]);
        break;
    case SYSCALL_LOCK_RELEASE:
        syscall_lock_release((lock_t*) user_context->cpu_regs[MIPS_REGISTER_A1]);
        break;
    case SYSCALL_CONDITION_CREATE:
        user_context->cpu_regs[MIPS_REGISTER_V0] =
            syscall_condition_create((cond_t*) user_context->cpu_regs[MIPS_REGISTER_A1]);
        break;
    case SYSCALL_CONDITION_WAIT:
        syscall_condition_wait((cond_t*) user_context->cpu_regs[MIPS_REGISTER_A1],
                (lock_t*) user_context->cpu_regs[MIPS_REGISTER_A2]);
        break;
    case SYSCALL_CONDITION_SIGNAL:
        syscall_condition_signal((cond_t*) user_context->cpu_regs[MIPS_REGISTER_A1],
                (lock_t*) user_context->cpu_regs[MIPS_REGISTER_A2]);
        break;
    case SYSCALL_CONDITION_BROADCAST:
        syscall_condition_broadcast((cond_t*) user_context->cpu_regs[MIPS_REGISTER_A1],
                (lock_t*) user_context->cpu_regs[MIPS_REGISTER_A2]);
        break;
    default:
        KERNEL_PANIC("Unhandled system call\n");
    }
    /* Move to next instruction after system call */
    user_context->pc += 4;
}
Exemple #17
0
static void
syscall_handler (struct intr_frame *f) 
{
  /* Validate the first addr of the stack frame */
  
  void *esp = utok_addr (f->esp, NULL);
  
  if (esp == NULL) {
    syscall_exit (-1);
    return;
  }
  
  enum SYSCALL_NUMBER call_number = *(enum SYSCALL_NUMBER *) esp;
  if (call_number < syscall_first_call || call_number > syscall_last_call) {
    syscall_exit (-1);
    return;
  }

  /* Buffer the arguments for validation */
  int argc = syscall_argc[call_number];
  uint32_t argbuf[3];

  int i = 0;
  for (; i < argc; i++) {
    /* Validate each argument  */
    void *vaddr = uptr_valid((uint32_t *) f->esp + 1 + i, f->esp);
    if (vaddr == NULL) {
      syscall_exit (-1);
      return;
    }
    /* Translate the argument to kernel virtual (== physical) memory */
    argbuf[i] = *(uint32_t *) vaddr;
  }
  
  int retval = 0;

  /* Switch based on call_number to delegate to corresponding syscall.
     Have not implemented several syscalls as of this project. 
     Use validation methods to check user-provided arguments.
  */
  switch (call_number) {
    case SYS_HALT:
      syscall_halt ();
      break;
    case SYS_EXIT:
      syscall_exit ((int) argbuf[0]);
      break;
    case SYS_EXEC:
      if (str_valid ((void *) argbuf[0], f->esp) == NULL) {
        syscall_exit (-1);
        return;
      }
      retval = syscall_exec ((char *) argbuf[0]);
      break;
    case SYS_WAIT:
      retval = syscall_wait ((int) argbuf[0]);
      break;
    case SYS_CREATE:
      if (str_valid ((char *) argbuf[0], f->esp) == NULL) {
        syscall_exit (-1);
        return;
      }
      retval = (int) syscall_create ((char *) argbuf[0],
                                     (unsigned) argbuf[1]);
      break;
    case SYS_REMOVE:
      if (!uptr_valid ((char *) argbuf[0], f->esp)) {
        syscall_exit (-1);
        return;
      }
      retval = (int) syscall_remove ((char *) argbuf[0]);
      break;
    case SYS_OPEN:
      if (str_valid ((char *) argbuf[0], f->esp) == NULL) {
        syscall_exit (-1);
        return;
      }
      retval = (int) syscall_open ((char *) argbuf[0]);
      break;
    case SYS_FILESIZE:
      retval = syscall_filesize ((int) argbuf[0]);
      break;
    case SYS_READ:
      if (buffer_valid ((void *) argbuf[1], f->esp, 
                        (unsigned) argbuf[2]) == NULL) {
        syscall_exit (-1);
        return;
      }
      retval = syscall_read ((int) argbuf[0],
                             (void *) argbuf[1],
                             (unsigned) argbuf[2]);
      break;
    case SYS_WRITE:
      if (buffer_valid ((void *) argbuf[1], f->esp, 
                        (unsigned) argbuf[2]) == NULL) {
        syscall_exit (-1);
        return;
      }
      retval = syscall_write ((int) argbuf[0],
                             (void *) argbuf[1],
                             (unsigned) argbuf[2]);
      break;
    case SYS_SEEK:
      syscall_seek ((int) argbuf[0], (unsigned) argbuf[1]);
      break;
    case SYS_TELL:
      retval = (int) syscall_tell ((int) argbuf[0]);
      break;
    case SYS_CLOSE:
      syscall_close ((int) argbuf[0]);
      break;
#ifdef VM
    case SYS_MMAP:
      // addr will be checked internally inside mmap
      retval = (int) syscall_mmap ((int) argbuf[0], (void *) argbuf[1]);
      break;
    case SYS_MUNMAP:
      syscall_munmap ((int) argbuf[0]);
      break;
#endif
    default:
      printf("unhandled system call!\n");
      thread_exit();
  }

  f->eax = retval;
}
Exemple #18
0
/* Handles syscalls.  Gets the syscall arguments off the stack (including the
   syscall number) then (either directly or with the aid of helper functions)
   executes the system call and places any return value into the eax register.
   Arguments should be parsed as soon as possible and the offset_lock should
   be held for the least possible amount of time. */
static void
syscall_handler (struct intr_frame *f)
{
  int sys_call;
  uint32_t ret_val = -1;
  void *arg0, *arg1, *arg2;
  struct fd_elem **fdt = thread_current()->open_files;

  /* Acquire lock before manipulating offset */
  lock_acquire(&offset_lock);
  offset = f->esp;
  sys_call = (int) next_arg();

  switch (sys_call) {
  case SYS_HALT:
    lock_release(&offset_lock);
    power_off();
    NOT_REACHED ();

  case SYS_EXIT:
    arg0 = next_arg();/* exit status */
    lock_release(&offset_lock);

    thread_current()->exit_controler->value = (int) arg0;
    thread_exit();
    NOT_REACHED ();

  case SYS_EXEC:
    arg0 = next_str(); /* executable name */
    lock_release(&offset_lock);

    ret_val = syscall_exec((const char *) arg0);
    break;

  case SYS_WAIT:
    arg0 = next_arg(); /* tid */
    lock_release(&offset_lock);

    ret_val = process_wait((tid_t) arg0);
    break;

  case SYS_CREATE:
    arg0 = next_str(); /* File name */
    arg1 = next_arg(); /* Size */
    lock_release(&offset_lock);

    lock_acquire(&fs_lock);
    ret_val = filesys_create((const char *) arg0, (unsigned) arg1);
    lock_release(&fs_lock);
    break;

  case SYS_REMOVE:
    arg0 = next_str();/* file name */
    lock_release(&offset_lock);

    lock_acquire(&fs_lock);
    ret_val = filesys_remove((const char *) arg0);
    lock_release(&fs_lock);
    break;

  case SYS_OPEN:
    arg0 = next_str(); /* file name */
    lock_release(&offset_lock);

    ret_val = syscall_open((const char *) arg0);
    break;

  case SYS_FILESIZE:
    arg0 = next_arg(); /* fd */
    lock_release(&offset_lock);

    lock_acquire(&fs_lock);
    ret_val = file_length(fdt[(int) arg0]->file);
    lock_release(&fs_lock);
    break;

  case SYS_READ:
    arg0 = next_arg(); /* fd */
    arg1 = next_arg(); /* buffer */
    arg2 = next_arg(); /* size */
    lock_release(&offset_lock);

    ret_val = syscall_read((int) arg0, arg1, (unsigned) arg2);
    break;

  case SYS_WRITE:
    arg0 = next_arg(); /* fd */
    arg1 = next_arg(); /* buffer */
    arg2 = next_arg(); /* size */
    lock_release(&offset_lock);

    ret_val = syscall_write((int) arg0, arg1, (unsigned) arg2);
    break;

  case SYS_SEEK:
    arg0 = next_arg(); /* fd */
    arg1 = next_arg(); /* position */
    lock_release(&offset_lock);

    lock_acquire(&fs_lock);
    file_seek(thread_current()->open_files[(int) arg0]->file, (unsigned) arg1);
    lock_release(&fs_lock);
    break;

  case SYS_TELL:
    arg0 = next_arg(); /* fd */
    lock_release(&offset_lock);

    lock_acquire(&fs_lock);
    ret_val = file_tell(fdt[(int) arg0]->file);
    lock_release(&fs_lock);
    break;

  case SYS_CLOSE:
    arg0 = next_arg(); /* fd */
    lock_release(&offset_lock);

    syscall_close((int) arg0);
    break;

  default:
    /* Invalid system call number. */
    lock_release(&offset_lock);
    ret_val = -1;
    break;
  }
  /* Put return value into eax register and return to normal execution. */
  f->eax = ret_val;
}
static void
syscall_handler (struct intr_frame *f)
{
  // XXX : EDIT WITH 'syscall.h' 'lib/user/syscall.c' 'lib/syscall-nr.h
  //printf ("system call!\n");
  void *now = f->esp;
  // XXX : Check PTR Range, and bash to syscall_exit(-1);
  if(!is_valid_ptr(now))
    syscall_exit(-1);
  int syscall_number = *(int *)(f->esp);
  int argc_size_table[22] = {  // CHECK syscall-nr.h
	  0,  // SYS_HALT (*) :0
	  1,  // SYS_EXIT (*) :1
	  1,  // SYS_EXEC (*) :2
	  1,  // SYS_WAIT (*) :3
	  2,  // SYS_CREATE   :4
	  1,  // SYS_REMOVE   :5
	  1,  // SYS_OPEN     :6
	  1,  // SYS_FILESIZE :7
	  3,  // SYS_READ (*) :8
	  3,  // SYS_WRITE (*):9
	  2,  // SYS_SEEK     :10
	  1,  // SYS_TELL     :11
	  1,  // SYS_CLOSE    :12  (proj 2-2)
	  2,  // SYS_MMAP
	  1,  // SYS_MUNMAP
	  1,  // SYS_CHDIR
	  1,  // SYS_MKDIR
	  2,  // SYS_READDIR
	  1,  // SYS_ISDIR
	  1,  // SYS_INUMBER
	  1,  // SYS_PIBONACCI
	  4   // SYS_SUM_OF_FOUR_INTEGERS
  };
  int argc_size = argc_size_table[syscall_number];
  //printf("SYSCALL %d SIZE %d\n", syscall_number, argc_size);
  void *argc[4] = {NULL,};
  {
    int i;
    for(i = 0; i < argc_size; i++){
      now += 4; // sizeof(void *);  // IT WILL USE 4 Bytes. (ref:man38).
      argc[i] = now;
	  // XXX : Check argument's ptr;
	  if(!is_valid_ptr(argc[i]))
		syscall_exit(-1);
	 // printf("%x\n", now);
    }
  }
  switch(syscall_number){
	default:
	case -1:
		break;
	case 0:  // SYS_HALT
		syscall_halt();
		break;
	case 1:  // SYS_EXIT
		syscall_exit(*(int *)argc[0]);
		break;
	case 2:  // SYS_EXEC
		f->eax = syscall_exec(*(const char **)argc[0]);
		break;
	case 3:  // SYS_WAIT
		//printf("CALLED SYS_WAIT!\n");
		f->eax = syscall_wait(*(pid_t *)argc[0]);
		break;
	case 4:  // SYS_CREATE
		f->eax = syscall_create(*(const char **)argc[0],
		                        *(unsigned *)argc[1]);
		break;
	case 5:  // SYS_REMOVE
		f->eax = syscall_remove(*(const char **)argc[0]);
		break;
	case 6:  // SYS_OPEN
		f->eax = syscall_open(*(const char **)argc[0]);
		break;
	case 7:  // SYS_FILESIZE
		f->eax = syscall_filesize(*(int *)argc[0]);
		break;
	case 8:  // SYS_READ
		f->eax = syscall_read(
				*(int *)argc[0],
				*(void **)argc[1],
				*(unsigned *)argc[2]
		);
		break;
	case 9:  // SYS_WRITE
		//printf("CALLED WRITE! %d %x %u\n", *(int *)argc[0], argc[1], *(unsigned *)argc[2]);
		f->eax = syscall_write(
				*(int *)argc[0],
				*(const void **)argc[1],
				*(unsigned *)argc[2]
		);
		break;
	case 10: // SYS_SEEK
		syscall_seek(*(int *)argc[0],
					 *(unsigned *)argc[1]
		);
		break;
	case 11: // SYS_TELL
		f->eax = syscall_tell(*(int *)argc[0]);
		break;
	case 12: // SYS_CLOSE
		syscall_close(*(int *)argc[0]);
		break;
	case 20:  // SYS_PIBONACCI
		f->eax = syscall_pibonacci(*(int *)argc[0]);
		break;
	case 21:  // SYS_SUM_OF_FOUR_INTEGERS
		f->eax = syscall_sum_of_four_integers(
				*(int *)argc[0],
				*(int *)argc[1],
				*(int *)argc[2],
				*(int *)argc[3]
		);
		break;
	// case *:
  }
  // printf("SYSCALL_RETURN: %d\n", f->eax);
  // thread_exit ();
  // XXX
}
Exemple #20
0
static void
syscall_handler (struct intr_frame *f) 
{
  int syscall_num;
  VALIDATE_AND_GET_ARG (f->esp, syscall_num, f);
  void *cur_sp = f->esp + sizeof (void *);

  /* store user program stack pointer to the thread's 
     user_esp before changing to kernel mode */
  struct thread *t = thread_current ();
  t->user_esp = f->esp;

  switch (syscall_num)
    {
      case SYS_HALT:
        syscall_halt (f, cur_sp);
        break;
      case SYS_EXIT:
        syscall_exit (f, cur_sp);
        break;
      case SYS_EXEC:
        syscall_exec (f, cur_sp);
        break;
      case SYS_WAIT:
        syscall_wait (f, cur_sp);
        break;
      case SYS_CREATE:
        syscall_create (f, cur_sp);
        break;
      case SYS_REMOVE:
        syscall_remove (f, cur_sp);
        break;
      case SYS_OPEN:
        syscall_open (f, cur_sp);
        break;
      case SYS_FILESIZE:
        syscall_filesize (f, cur_sp);
        break;
      case SYS_READ:
        syscall_read (f, cur_sp);
        break;
      case SYS_WRITE:
        syscall_write (f, cur_sp);
        break;
      case SYS_SEEK:
        syscall_seek (f, cur_sp);
        break;
      case SYS_TELL:
        syscall_tell (f, cur_sp);
        break;
      case SYS_CLOSE:
        syscall_close (f, cur_sp);
        break;
      case SYS_MMAP:
        syscall_mmap (f, cur_sp);
        break;
      case SYS_MUNMAP:
        syscall_unmmap (f, cur_sp);
        break;
      default :
        printf ("Invalid system call! #%d\n", syscall_num);
        syscall_thread_exit (f, -1);
        break;
    }
}