Пример #1
0
void syscall_linux(void) {
  assert(current != NULL);
  struct trapframe *tf = current->tf;
  uint32_t arg[6];
  int num = tf->tf_regs.reg_r[MIPS_REG_V0] - 4000;
  if (num >= 0 && num < 1000) {
    if (linux_syscall_table[num] != NULL) {
      arg[0] = tf->tf_regs.reg_r[MIPS_REG_A0];
      arg[1] = tf->tf_regs.reg_r[MIPS_REG_A1];
      arg[2] = tf->tf_regs.reg_r[MIPS_REG_A2];
      arg[3] = tf->tf_regs.reg_r[MIPS_REG_A3];
      uint32_t* stack_pointor = tf->tf_regs.reg_r[MIPS_REG_SP];
      arg[4] = stack_pointor[4];
      arg[5] = stack_pointor[5];
      //kprintf("MIPS_sys $%d $%d\n", current->pid, num);
      //TODO: 0 indicates that syscall always suceeded, not reasonable but seems
      //It works. Need to be set before syscall because fork won't return.
      if(num == __NR_pipe) {
        int fd[2];
        if(file_pipe(fd) != 0) {
          tf->tf_regs.reg_r[MIPS_REG_A3] = 1;
        }
        else {
          tf->tf_regs.reg_r[MIPS_REG_A3] = 0;
          tf->tf_regs.reg_r[MIPS_REG_V0] = fd[0];
          tf->tf_regs.reg_r[MIPS_REG_V1] = fd[1];
          kprintf("pipe %d %d\n",  fd[0],  fd[1]);
        }
      }
      else {
        tf->tf_regs.reg_r[MIPS_REG_A3] = 0;
        tf->tf_regs.reg_r[MIPS_REG_V0] = linux_syscall_table[num] (arg);
      }
      /*if(num == __NR_read || num == __NR_write) {
        if(((int)tf->tf_regs.reg_r[MIPS_REG_V0]) < 0) {
          tf->tf_regs.reg_r[MIPS_REG_A3] = 1;
        }
      }*/
      return;
    }
  }
  print_trapframe(tf);
  panic("Undefined Linux OABI syscall %d, pid = %d, name = %s.\n",
      num, current->pid, current->name);
}
Пример #2
0
int
sysfile_pipe(int *fd_store) {
    struct mm_struct *mm = current->mm;
    int ret, fd[2];
    if (!user_mem_check(mm, (uintptr_t)fd_store, sizeof(fd), 1)) {
        return -E_INVAL;
    }
    if ((ret = file_pipe(fd)) == 0) {
        lock_mm(mm);
        {
            if (!copy_to_user(mm, fd_store, fd, sizeof(fd))) {
                ret = -E_INVAL;
            }
        }
        unlock_mm(mm);
        if (ret != 0) {
            file_close(fd[0]), file_close(fd[1]);
        }
    }
    return ret;
}