Пример #1
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");
   }
}
Пример #2
0
int cmd_show(int argc, char** argv) {
  if (argc != 2) {
    printf("Usage: show <file>\n");
    return 1;
  }
  int fd;
  if ((fd=syscall_open(argv[1])) < 0) {
    printf("Could not open %s.  Reason: %d\n", argv[1], fd);
    return 1;
  }

  int rd;
  char buffer[BUFFER_SIZE];
  while ((rd = syscall_read(fd, buffer, BUFFER_SIZE))) {
    int wr=0, thiswr;
    while (wr < rd) {
      if ((thiswr = syscall_write(1, buffer+wr, rd-wr)) <= 0) {
        printf("\nCall to syscall_write() failed.  Reason: %d.\n", wr);
        syscall_close(fd);
        return 1;
      }
      wr += thiswr;
    }
  }
  if (rd < 0) {
    printf("\nCall to syscall_read() failed.  Reason: %d.\n", rd);
    syscall_close(fd);
    return 1;
  } else {
    syscall_close(fd);
    return 0;
  }
}
Пример #3
0
static ssize_t socket_read_plain(struct bus *b, listener *l, int pfd_i, connection_info *ci) {
    ssize_t accum = 0;
    while (ci->to_read_size > 0) {
        ssize_t size = syscall_read(ci->fd, l->read_buf, ci->to_read_size);
        if (size == -1) {
            BUS_LOG_SNPRINTF(b, 6, LOG_LISTENER, b->udata, 64,
                             "read: size %zd, errno %d", size, errno);
            if (errno == EAGAIN) {
                errno = 0;
                return accum;
            } else if (Util_IsResumableIOError(errno)) {
                errno = 0;
                continue;
            } else {
                BUS_LOG_SNPRINTF(b, 3, LOG_LISTENER, b->udata, 64,
                                 "read: socket error reading, %d", errno);
                set_error_for_socket(l, pfd_i, ci->fd, RX_ERROR_READ_FAILURE);
                errno = 0;
                return -1;
            }
        }

        if (size > 0) {
            BUS_LOG_SNPRINTF(b, 5, LOG_LISTENER, b->udata, 64,
                             "read: %zd", size);
            sink_socket_read(b, l, ci, size);
            accum += size;
        } else {
            return accum;
        }
    }
    return accum;
}
Пример #4
0
int main(void)
{

  heap_init();

  char buffer[64];
  char startString[] = "Please write 10 characters: \n";
  char endString[] = "\nTest complete.\n";

  void *pointer = malloc(sizeof(buffer));



  syscall_write(FILEHANDLE_STDIN, startString, 30);

  syscall_read(FILEHANDLE_STDIN, buffer, 10);

  syscall_write(FILEHANDLE_STDIN, buffer, 10);

  syscall_write(FILEHANDLE_STDIN, endString, 16);

  syscall_halt();
  
  return 0;
}
Пример #5
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.
     */

    int retval;

    switch(user_context->cpu_regs[MIPS_REGISTER_A0]) {
    case SYSCALL_HALT:
        halt_kernel();
        break;
    case SYSCALL_EXEC:
        retval = (int) process_spawn((char*) user_context->cpu_regs[MIPS_REGISTER_A1]);
        user_context->cpu_regs[MIPS_REGISTER_V0] = retval;
        break;
    case SYSCALL_EXIT:
        /* Resources are cleaned up in process_finish(...) */
        process_finish(user_context->cpu_regs[MIPS_REGISTER_A1]);
        break;
    case SYSCALL_JOIN:
        retval = process_join(user_context->cpu_regs[MIPS_REGISTER_A1]);
        user_context->cpu_regs[MIPS_REGISTER_V0] = retval;
        break;
    case SYSCALL_READ:
        {
            int fhandle = user_context->cpu_regs[MIPS_REGISTER_A1];
            int buffer = user_context->cpu_regs[MIPS_REGISTER_A2];
            int length = user_context->cpu_regs[MIPS_REGISTER_A3];

            int retval = syscall_read(fhandle, (void *)buffer, length);
            user_context->cpu_regs[MIPS_REGISTER_V0] = retval;
        }
        break;
    case SYSCALL_WRITE:
        {
            int fhandle = user_context->cpu_regs[MIPS_REGISTER_A1];
            int buffer = user_context->cpu_regs[MIPS_REGISTER_A2];
            int length = user_context->cpu_regs[MIPS_REGISTER_A3];

            int retval = syscall_write(fhandle, (void *)buffer, length);
            user_context->cpu_regs[MIPS_REGISTER_V0] = retval;
        }
        break;
    default:
        KERNEL_PANIC("Unhandled system call\n");
    }

    /* Move to next instruction after system call */
    user_context->pc += 4;
}
Пример #6
0
int main(void) {

	char file[] = "[arkimedes]hej";
	int handle = syscall_open((char const*) &file);	

	char buffer[128];
	char buffer2[128];

	syscall_read(handle, &buffer, 4);
	syscall_write(handle, &buffer, 4);

	syscall_seek(handle, 0);
	syscall_read(handle, &buffer2, 11);
	syscall_write(FILEHANDLE_STDOUT, &buffer2, 11);

	syscall_close(handle);
	syscall_delete((char const*) &file);

	char file2[] = "[arkimedes]rasputin";
	syscall_create((char const*) &file2, 11);

	char buffer3[] = "\ngorbatjov\n";
	handle = syscall_open((char const*) &file2);	
	
	syscall_write(handle, &buffer3, 11);

	int ret_code = syscall_seek(handle, 12);
	printf("\n%d\n", ret_code);

	syscall_seek(handle, 0);
	syscall_read(handle, &buffer3, 11);
	syscall_write(FILEHANDLE_STDOUT, &buffer3, 11);	

	syscall_close(handle);

	char file3[] = "[arkimedes]putin";
	syscall_create((char const*) &file3, 11);
	handle = syscall_open((char const*) &file3);	

	char buffer4[] = "\ngorbad\n";
	syscall_write(handle, &buffer4, 11);
	
	return 0;
}
Пример #7
0
int main(void)
{
  int pipeid;
  char string[4];
  pipeid = syscall_open("[pipe]test");
  syscall_read(pipeid, string, 4);
  syscall_write(1, string, 4);
  printf("\n");
  return 0;
}
Пример #8
0
int main(void) {
    char c;
    
    while(1){
        syscall_read(stdin,&c,1);
        syscall_write(stdout,&c,1);
        if (c == 'q') syscall_halt(); // press 'q' to quit
    }
    
    return 0;
}
Пример #9
0
int main(int argc, char  **argv)
{
	char s[10000];
	int k,sum=0;
	int fd0;
	FILE *fd1;

	initialize();

	if (argc < 3)
	{
		printf("Usage:\n\ncpfile -o fimage-source host-target\ncpfile host-source fimage-target\n");
		exit(0);
	}
	if (strcmp(argv[1], "-o") == 0)
	{
		fd0 = syscall_open(argv[2],O_RDONLY,0);
		fd1 = fopen(argv[3],"wb");

		if (fd0 < 0 || fd1 < 0)
		{
			printf("Error opening input/output files\n");
			exit(0);
		}
		while ((k=syscall_read(fd0, s, 10000))>0)
		{
			fwrite(s,k,1,fd1);
			sum += k;
		}
		syscall_close(fd0);
		fclose(fd1);
	}
	else
	{
		fd0 = syscall_open(argv[2],O_WRONLY,0);
		fd1 = fopen(argv[1],"rb");
		if (fd0 < 0 || fd1 < 0)
		{
			printf("Error opening input/output files\n");
			exit(0);
		}
		
		while ((k=fread(s, 1, 10000, fd1))>0)
		{
			syscall_write(fd0,s,k);
			sum += k;
		}
		syscall_close(fd0);
		fclose(fd1);
	}
	closeall();
	//printf("Image copied\n");
	return 0;
}
Пример #10
0
int main() 
{
  /* setup needed variables */
  int fhin = FILEHANDLE_STDIN;
  char* wbuff = "Oh hello there!! \nwhat is your name?\n";
  char rbuff[64];
  int c;
  
  /* test the calls */
  
  syscall_write(fhin,wbuff,37);
  
  c = syscall_read(fhin,rbuff,63);
  
  wbuff = "Hello";
  syscall_write(fhin,wbuff,5);
  
  syscall_write(fhin,rbuff,c);
  
  wbuff = ", how are you doing today?\n";
  syscall_write(fhin,wbuff,27);
  
  c = syscall_read(fhin,rbuff,63);
  
  wbuff = "Oh you're doing ";
  syscall_write(fhin,wbuff,16);
  
  syscall_write(fhin,rbuff,c);
  
  wbuff = "!!!\n";
  syscall_write(fhin,wbuff, 4);
    
  wbuff = "Go on have a good day now!!";
  syscall_write(fhin,wbuff, 28);
  
  /* ensure proper system shut down */

  syscall_halt();
  
  return 0;
}
Пример #11
0
int cmd_cmp(int argc, char** argv) {
  /* Note that this command is absurdly slow.  Never do single-byte
     reads in the real world. */
  if (argc != 3 && argc != 4) {
    printf("Usage: cmp <file1> <file2>\n");
    return 1;
  }
  int fd1, fd2;
  if ((fd1=syscall_open(argv[1])) < 0) {
    printf("Could not open %s.  Reason: %d\n", argv[1], fd1);
    return 1;
  }
  if ((fd2=syscall_open(argv[2])) < 0) {
    printf("Could not open file %s.  Reason: %d\n", argv[2], fd2);
    syscall_close(fd1);
    return 1;
  }
  char c1, c2;
  int rd1, rd2, i=0;
  do {
    rd1=syscall_read(fd1,&c1,1);
    rd2=syscall_read(fd2,&c2,1);
    clearline();
    printf("Comparing byte %d... ", i);
    if (rd1 != rd2) {
      printf("Files differ: not the same size.\n");
      break;
    } else if (c1 != c2) {
      printf("Files differ at position %d.\n", i);
      break;
    }
    i++;
  } while (rd1 != 0);
  printf("\n");
  syscall_close(fd1);
  syscall_close(fd2);
  return 0;
}
Пример #12
0
int cmd_cp(int argc, char** argv) {
  if (argc != 3 && argc != 4) {
    printf("Usage: cp <from> <to> [size]\n");
    return 1;
  }
  int fd1, fd2;
  int size = argc == 4 ? atoi(argv[3]) : 0;
  if ((fd1=syscall_open(argv[1])) < 0) {
    printf("Could not open %s.  Reason: %d\n", argv[1], fd1);
    return 1;
  }
  if ((fd2=syscall_create(argv[2], size)) < 0) {
    printf("Could not create %s with initial size %d.  Reason: %d\n", argv[2], size, fd2);
    syscall_close(fd1);
    return 1;
  }
  if ((fd2=syscall_open(argv[2])) < 0) {
    printf("Could not open newly created file %s.  Reason: %d\n", argv[2], fd2);
    syscall_close(fd1);
    return 1;
  }
  int ret, i, rd, wr;
  int totalread = 0, totalwritten = 0;
  char buffer[BUFFER_SIZE];
  while ((rd = syscall_read(fd1, buffer, BUFFER_SIZE))) {
    i = 0;
    totalread += rd;
    clearline();
    printf("Read %d bytes, wrote %d bytes.", totalread, totalwritten);
    while (i < rd) {
      if ((wr=syscall_write(fd2, buffer+i, rd-i)) <= 0) {
        printf("\nCall to syscall_write() failed.  Reason: %d.\n", wr);
        if (wr == 0) {
          printf("Did you remember to make the destination file big enough?\n");
        }
        ret=1;
        goto exit;
      }
      totalwritten += wr;
      i += wr;
      clearline();
      printf("Read %d bytes, wrote %d bytes.", totalread, totalwritten);
    }
  }
 exit:
  printf("\n");
  syscall_close(fd1);
  syscall_close(fd2);
  return ret;
}
Пример #13
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;
  }
}
Пример #14
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;
}
Пример #15
0
int main(void)
{
    char buffer[64];
    char *ptr = buffer;
    char intro[20] = "Press a button!";
    char *introptr = intro;
    int a = syscall_write(1, introptr, 15);
    int b = syscall_read(0, ptr, 10);
    int c = syscall_write(1, ptr, 10);   
    
    a = a;
    b = b;
    c = c;

    syscall_halt();
    
    return 0;
}
Пример #16
0
int main()
{
    char buff[20];
    syscall_delete(file1);
    if (syscall_create(file1, 100) < 0)
        fail("Couldn't create file :(\n");
    int fd = syscall_open(file1);
    if (fd < 0)
        fail("Couldn't open file :(\n");
    printf("Wrote %d bytes\n", syscall_write(fd, "Teststring!\n", 11));

    if (syscall_seek(fd, 0) < 0)
        fail("Couldn't seek :(\n");

    printf("Read %d bytes\n", syscall_read(fd, buff, 20));
    printf(buff);

    syscall_halt();
    return 0;
}
Пример #17
0
/**
 * Handle system calls. Interrupts are enabled when this function is
 * called.
 */
uintptr_t syscall_entry(uintptr_t syscall,
                        uintptr_t arg0, uintptr_t arg1, uintptr_t arg2)
{
  arg0 = arg0;
  arg1 = arg1;
  arg2 = arg2;
  /* 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(syscall) {
  case SYSCALL_HALT:
    halt_kernel();
    break;
  case SYSCALL_READ:
    return syscall_read((void*)arg1);
    break;
  case SYSCALL_WRITE:
    return syscall_write((const void*)arg1, (int)arg2);
    break;
  case SYSCALL_SPAWN:
    return syscall_spawn((char const*)arg0, (void*) arg1);
    break;
  case SYSCALL_EXIT:
    syscall_exit((int)arg0);
    break;
  case SYSCALL_JOIN:
    return process_join((int)arg0);
    break;
  default:
    KERNEL_PANIC("Unhandled system call\n");
  }

  return 0;
}
Пример #18
0
/* ------------------------------------------------------------------------ *
 * Read either from the fd directly or from its queue.                      *
 * ------------------------------------------------------------------------ */
int io_read(int fd, void *buf, size_t n)
{
  /* Catch invalid arguments */
  if(fd < 0) return -1;
  if(n == 0) return 0;

  /* fd is queued, read from the receive queue */
  if(io_list[fd].control.recvq)
  {
    /* Receive queue is empty */
    if(io_list[fd].recvq.size == 0)
    {
      syscall_errno = EAGAIN;
      return -1;
    }

    return queue_read(&io_list[fd].recvq, buf, n);
  }

  /* Read directly from fd */
  switch(io_list[fd].type)
  {
    case FD_SOCKET:
#ifdef HAVE_SSL
      if(io_list[fd].ssl)
        return ssl_read(fd, buf, IO_READ_SIZE);
      else
#endif
      return syscall_recv(fd, buf, n, 0);
    default:
    case FD_FILE:
    case FD_PIPE:
      return syscall_read(fd, buf, n);
  }

  return -1;
}
Пример #19
0
int main(void)
{
  int fid;
  int len = 512;
  int len2 = 0;
  char buffer[512];

  fid = syscall_open("[pipe]test");
  printf("Fid was %d\n", fid);
  
  
  // to read from buffer, until we read 0 bytes the string, use a loop
  while(len2 < len){
    // write to the buffer, with offset len2, until all was written
    syscall_seek(fid,0);
    len2 += syscall_read(fid,buffer + len2,len);

    printf("read ret was %d\n", len2);
  }

  // print the length of the string in buffer
  printf("Length of string is %d\n", strlen(buffer));
  return 0;
}
Пример #20
0
Файл: lib.c Проект: Tayacan/OSM
/* Read character from standard input, without echoing.  Returns a
   non-negative integer on success, which can be casted to char. */
int getc_raw(void)
{
  char c;
  syscall_read(stdin, &c, 1);
  return c;
}
Пример #21
0
Файл: lib.c Проект: PtxDK/OSM
/* Read character from standard input, without echoing.  Returns a
   non-negative integer on success, which can be casted to char. */
int getc_raw(void)
{
  char c;
  syscall_read(FILEHANDLE_STDIN, &c, 1);
  return c;
}
Пример #22
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;
}
Пример #23
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;
    }
}
Пример #24
0
int systemcall(struct PAR_REGS *regs)
{
	char *cpp1, *cpp2, **cppp1; //3, *cpp4, *cpp5, *cpp6, **cppp1, **cppp2;
	int i, ip1, ip2;
	//unsigned long old_cr0;
	
	switch (regs->eax) // Sys call number ?
	{
		case 0: return syscall_test();
		case 1:
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_open(CHARPPAR(regs->ebx), INTPAR(regs->ebx+4), INTPAR(regs+4+4));
		case 2: return syscall_close(INTPAR(regs->ebx));
		case 3:
			cpp1 = CHARPPAR(regs->ebx+4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_read(INTPAR(regs->ebx), cpp1, INTPAR(regs->ebx+4+4));
		case 4: 
			cpp1 = CHARPPAR(regs->ebx+4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_write(INTPAR(regs->ebx), cpp1, INTPAR(regs->ebx+4+4));
		case 5: return syscall_lseek(INTPAR(regs->ebx), INTPAR(regs->ebx+4), INTPAR(regs->ebx+4+4));
		case 6: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_mkdir(cpp1, INTPAR(regs->ebx+4));
		case 7: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_rmdir(cpp1);
		case 8: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_chdir(cpp1);
		case 9: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_creat(cpp1, INTPAR(regs->ebx+4));
		case 10:
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_rename(CHARPPAR(regs->ebx), CHARPPAR(regs->ebx+4));
		case 11: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return (int) syscall_opendir(CHARPPAR(regs->ebx), (DIR *)CHARPPAR(regs->ebx+4));
		case 12: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_closedir((DIR *) CHARPPAR(regs->ebx));
		case 13: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return (int) syscall_readdir((DIR *)CHARPPAR(regs->ebx));
		case 14: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_stat(CHARPPAR(regs->ebx),(struct stat *)CHARPPAR(regs->ebx+4));
		case 15: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_unlink(CHARPPAR(regs->ebx));
		case 16: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_chmod(CHARPPAR(regs->ebx),(mode_t)INTPAR(regs->ebx+4));
		case 17:
			ip1 = INTPAR(regs->ebx);
			return syscall_dup(ip1);
		case 18:
			ip1 = INTPAR(regs->ebx);
			ip2 = INTPAR(regs->ebx + 4);
			return syscall_dup2(ip1, ip2);
		case 19: syscall_setcursor( INTPAR(regs->ebx),INTPAR(regs->ebx+4)); return 0;
		case 20: return syscall_getchar();
		case 21: return syscall_getchare();
		case 22: return syscall_getscanchar();
		case 23: return syscall_putchar(CHARPAR(regs->ebx));
		case 24: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_puts(CHARPPAR(regs->ebx));
		case 25:
			cpp1 = CHARPPAR(regs->ebx);
			ip1 = INTPAR(regs->ebx + 4);
			syscall_seekdir((DIR *)cpp1, ip1);
			return 0;
		case 26:
			cpp1 = CHARPPAR(regs->ebx);
			return syscall_telldir((DIR *)cpp1);
		case 27:
			cpp1 = CHARPPAR(regs->ebx);
			syscall_rewinddir((DIR *)cpp1);
			return 0;
		case 32: 
			cpp1 = CHARPPAR(regs->ebx+12);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_readblocks(INTPAR(regs->ebx), INTPAR(regs->ebx+4), INTPAR(regs->ebx+8), CHARPPAR(regs->ebx+12));
		case 33: 
			cpp1 = CHARPPAR(regs->ebx+12);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_writeblocks(INTPAR(regs->ebx), INTPAR(regs->ebx+4), INTPAR(regs->ebx+8), CHARPPAR(regs->ebx+12));
		case 34: syscall_sync(0); return 0;
		case 50: syscall_tsleep(INTPAR(regs->ebx)); return 0;
		case 60: 
			cpp1 = CHARPPAR(regs->ebx + 4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_tsendto(SHORTPAR(regs->ebx), CHARPPAR(regs->ebx+4), INTPAR(regs->ebx+8), INTPAR(regs->ebx+12), INTPAR(regs->ebx+16), SHORTPAR(regs->ebx+20));
		case 62: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx + 8);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_trecvfrom(CHARPPAR(regs->ebx), INTPAR(regs->ebx+4), SHORTPPAR(regs->ebx+8), INTPAR(regs->ebx+12));
		case 65: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cppp1 = (char **)CHARPPAR(regs->ebx+4);
			i = 0;
			while (cppp1[i] != NULL)
			{
				if (cppp1[i] < KERNELEND) return EINVALIDPTR;
				i++;
			}
			cppp1 = (char **)CHARPPAR(regs->ebx+8);
			i = 0;
			while (cppp1[i] != NULL)
			{
				if (cppp1[i] < KERNELEND) return EINVALIDPTR;
				i++;
			}
			return syscall_exectask(CHARPPAR(regs->ebx), (char **)CHARPPAR(regs->ebx+4), (char **)CHARPPAR(regs->ebx+8), INTPAR(regs->ebx+12));
		case 66: syscall_exit(INTPAR(regs->ebx)); return 0;
		case 70:
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+4);
			if (cpp1 < KERNELEND && cpp1 != NULL) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+8);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+12);
			if (cpp1 < KERNELEND && cpp1 != NULL) return EINVALIDPTR;
			return syscall_pthread_create((pthread_t *)INTPPAR(regs->ebx), (pthread_attr_t *)CHARPPAR(regs->ebx+4), (void *(*)(void *))INTPPAR(regs->ebx+8), (void *)CHARPPAR(regs->ebx+12));
		case 71: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND && cpp1 != NULL) return EINVALIDPTR;
			syscall_pthread_exit((void *)CHARPPAR(regs->ebx)); return 0;
		case 72: 
			cpp1 = CHARPPAR(regs->ebx+4);
			if (cpp1 < KERNELEND && cpp1 != NULL) return EINVALIDPTR;
			return syscall_pthread_join((pthread_t)INTPAR(regs->ebx), (void **)CHARPPAR(regs->ebx+4));
		case 73: return syscall_pthread_detach((pthread_t)INTPAR(regs->ebx));
		case 74: return syscall_pthread_yield();
		case 75: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+4);
			if (cpp1 < KERNELEND && cpp1 != NULL) return EINVALIDPTR;
			return syscall_pthread_mutex_init((pthread_mutex_t *)INTPAR(regs->ebx), (pthread_mutexattr_t *)CHARPPAR(regs->ebx+4));
		case 76: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_pthread_mutex_trylock((pthread_mutex_t *)INTPAR(regs->ebx));
		case 77: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_pthread_mutex_lock((pthread_mutex_t *)INTPAR(regs->ebx));
		case 78: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_pthread_mutex_unlock((pthread_mutex_t *)INTPAR(regs->ebx));
		case 79: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+4);
			if (cpp1 < KERNELEND && cpp1 != NULL) return EINVALIDPTR;
			return syscall_pthread_cond_init((pthread_cond_t *)INTPAR(regs->ebx), (pthread_condattr_t *)CHARPPAR(regs->ebx+4));
		case 80: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+4);
			if (cpp1 < KERNELEND && cpp1 != NULL) return EINVALIDPTR;
			return syscall_pthread_cond_wait((pthread_cond_t *)INTPAR(regs->ebx), (pthread_mutex_t *)INTPPAR(regs->ebx+4));
		case 81: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_pthread_cond_signal((pthread_cond_t *)INTPAR(regs->ebx));
		case 82: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_pthread_cond_broadcast((pthread_cond_t *)INTPAR(regs->ebx));
		case 83: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+4);
			if (cpp1 < KERNELEND && cpp1 != NULL) return EINVALIDPTR;
			return syscall_pthread_barrier_init((pthread_barrier_t *)INTPAR(regs->ebx), (pthread_barrierattr_t *)INTPPAR(regs->ebx+4), INTPAR(regs->ebx+8));
		case 84: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_pthread_barrier_wait((pthread_barrier_t *)INTPAR(regs->ebx));
		case 90: return syscall_socket(INTPAR(regs->ebx), INTPAR(regs->ebx+4), INTPAR(regs->ebx+8));
		case 91: 
			cpp1 = CHARPPAR(regs->ebx+4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_bind(INTPAR(regs->ebx), (struct sockaddr *)INTPPAR(regs->ebx+4), SHORTPAR(regs->ebx+8));
		case 92: 
			cpp1 = CHARPPAR(regs->ebx + 4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_recv(INTPAR(regs->ebx), (void *)CHARPPAR(regs->ebx+4), (size_t)INTPAR(regs->ebx+8), INTPAR(regs->ebx+12));
		case 93: 
			cpp1 = CHARPPAR(regs->ebx + 4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+16);
			if (cpp1 < KERNELEND && cpp1 != NULL) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+20);
			if (cpp1 < KERNELEND && cpp1 != NULL) return EINVALIDPTR;
			return syscall_recvfrom(INTPAR(regs->ebx), (void *)CHARPPAR(regs->ebx+4), (size_t)INTPAR(regs->ebx+8), INTPAR(regs->ebx+12), (struct sockaddr *)CHARPPAR(regs->ebx+16), (socklen_t *)SHORTPPAR(regs->ebx+20));
		case 94: 
			cpp1 = CHARPPAR(regs->ebx + 4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_send(INTPAR(regs->ebx), (void *)CHARPPAR(regs->ebx+4), (size_t)INTPAR(regs->ebx+8), INTPAR(regs->ebx+12));
		case 95: 
			cpp1 = CHARPPAR(regs->ebx + 4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx + 16);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_sendto(INTPAR(regs->ebx), (void *)CHARPPAR(regs->ebx+4), (size_t)INTPAR(regs->ebx+8), INTPAR(regs->ebx+12), (struct sockaddr *)CHARPPAR(regs->ebx+16), (socklen_t)SHORTPAR(regs->ebx+20));
		case 96: 
			cpp1 = CHARPPAR(regs->ebx + 4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_connect(INTPAR(regs->ebx), (struct sockaddr *)CHARPPAR(regs->ebx+4), (socklen_t)SHORTPAR(regs->ebx+8));
		case 97: 
			cpp1 = CHARPPAR(regs->ebx + 4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx + 8);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_accept(INTPAR(regs->ebx), (struct sockaddr *)CHARPPAR(regs->ebx+4), (socklen_t *)CHARPPAR(regs->ebx+8));
		case 98: return syscall_listen(INTPAR(regs->ebx), INTPAR(regs->ebx+4));
		case 99: return syscall_kill(INTPAR(regs->ebx));
		case 100: 
			cpp1 = CHARPPAR(regs->ebx + 4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_getprocinfo(INTPAR(regs->ebx), (struct uprocinfo *)INTPPAR(regs->ebx+4));
		case 101: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_getpids(INTPPAR(regs->ebx), INTPAR(regs->ebx+4));
		case 102: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_sem_init((sem_t *)(CHARPPAR(regs->ebx)), INTPAR(regs->ebx+4), (unsigned int)INTPAR(regs->ebx+8));
		case 103: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_sem_destroy((sem_t *)(CHARPPAR(regs->ebx)));
		case 104: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+16);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return (int)syscall_sem_open(CHARPPAR(regs->ebx), INTPAR(regs->ebx+4), (mode_t)INTPAR(regs->ebx+8), INTPAR(regs->ebx+12), (sem_t *)CHARPPAR(regs->ebx+16));
		case 105: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_sem_close((sem_t *)(CHARPPAR(regs->ebx)));
		case 106: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_sem_unlink(CHARPPAR(regs->ebx));
		case 107: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_sem_wait((sem_t *)(CHARPPAR(regs->ebx)));
		case 108: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_sem_trywait((sem_t *)(CHARPPAR(regs->ebx)));
		case 109: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_sem_timedwait((sem_t *)(CHARPPAR(regs->ebx)), (const struct timespec *)CHARPPAR(regs->ebx+4));
		case 110: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_sem_post((sem_t *)(CHARPPAR(regs->ebx)));
		case 111: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_sem_getvalue((sem_t *)(CHARPPAR(regs->ebx)), INTPPAR(regs->ebx+4));
		case 112: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND && cpp1 != NULL) return EINVALIDPTR;
			return (int)syscall_time((time_t *)(CHARPPAR(regs->ebx)));
		case 113: return (int)syscall_pthread_self();
		case 114: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND && cpp1 != NULL) return EINVALIDPTR;
			return syscall_brk((void *)CHARPPAR(regs->ebx));
		case 115:
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+8);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_gettsc((unsigned int *)INTPPAR(regs->ebx), (unsigned int *)INTPPAR(regs->ebx+4), (unsigned int *)INTPPAR(regs->ebx+8));

		case 140:
			print_core_info();
			print_minf_statistics();
			return 0;

		case 147:
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_wait(INTPPAR(regs->ebx));
		case 148:
			return syscall_pageinfo(INTPAR(regs->ebx), INTPAR(regs->ebx+4));
		case 153:
			syscall_machid();
			return 0;
		case 154:
			return syscall_getcharf(INTPAR(regs->ebx));
		case 155:
			return syscall_ungetcharf(INTPAR(regs->ebx), INTPAR(regs->ebx+4));
		case 156:
			printk("broadcast called\n");
			return syscall_broadcast(INTPAR(regs->ebx), CHARPPAR(regs->ebx+4), INTPAR(regs->ebx+8));
		case 157:
			return syscall_primalloc((unsigned int)INTPAR(regs->ebx));

		case 158:
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_prifree((void *)CHARPPAR(regs->ebx), (unsigned int)INTPAR(regs->ebx+4));
		case 202:
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp2 = CHARPPAR(regs->ebx + 4);
			if (cpp2 < KERNELEND) return EINVALIDPTR;
			mark_tsc((unsigned int *)cpp1, (unsigned int *)cpp2);
			return 0;

		case 203:
			return (secs * 1000 + millesecs);
			
		case 204:
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_pthread_mutex_destroy((pthread_mutex_t *) cpp1);
		
		default: return syscall_notimplemented(regs->eax);
	}
}
Пример #25
0
bool BusPoll_OnCompletion(struct bus *b, int fd) {
    /* POLL in a pipe */
    #ifndef TEST
    struct pollfd fds[1];
    #endif
    fds[0].fd = fd;
    fds[0].events = POLLIN;

    for (;;) {
        BUS_LOG(b, 5, LOG_SENDING_REQUEST, "Polling on completion...tick...", b->udata);
        #ifdef TEST
        errno = poll_errno;
        #endif
        BUS_LOG_SNPRINTF(b, 5, LOG_SENDING_REQUEST, b->udata, 64,
            "poll_on_completion, polling %d", fd);
        int res = syscall_poll(fds, 1, -1);
        BUS_LOG_SNPRINTF(b, 5, LOG_SENDING_REQUEST, b->udata, 64,
            "poll_on_completion for %d, res %d (errno %d)", fd, res, errno);
        if (res == -1) {
            if (Util_IsResumableIOError(errno)) {
                BUS_LOG_SNPRINTF(b, 5, LOG_SENDING_REQUEST, b->udata, 64,
                    "poll_on_completion, resumable IO error %d", errno);
                errno = 0;
                continue;
            } else {
                BUS_LOG_SNPRINTF(b, 1, LOG_SENDING_REQUEST, b->udata, 64,
                    "poll_on_completion, non-resumable IO error %d", errno);
                return false;
            }
        } else if (res == 1) {
            uint16_t msec = 0;
            #ifndef TEST
            uint8_t read_buf[sizeof(uint8_t) + sizeof(uint16_t)];
            #endif

            if (fds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) {
                BUS_LOG(b, 1, LOG_SENDING_REQUEST, "failed (broken alert pipe)", b->udata);
                return false;
            }

            BUS_LOG(b, 3, LOG_SENDING_REQUEST, "Reading alert pipe...", b->udata);
            #ifdef TEST
            errno = read_errno;
            #endif
            ssize_t sz = syscall_read(fd, read_buf, sizeof(read_buf));

            if (sz == sizeof(read_buf)) {
                /* Payload: little-endian uint16_t, msec of backpressure. */
                assert(read_buf[0] == LISTENER_MSG_TAG);

                msec = (read_buf[1] << 0) + (read_buf[2] << 8);
                Bus_BackpressureDelay(b, msec, LISTENER_BACKPRESSURE_SHIFT);
                BUS_LOG(b, 4, LOG_SENDING_REQUEST, "sent!", b->udata);
                return true;
            } else if (sz == -1) {
                if (Util_IsResumableIOError(errno)) {
                    BUS_LOG_SNPRINTF(b, 5, LOG_SENDING_REQUEST, b->udata, 64,
                        "poll_on_completion read, resumable IO error %d", errno);
                    errno = 0;
                    continue;
                } else {
                    BUS_LOG_SNPRINTF(b, 2, LOG_SENDING_REQUEST, b->udata, 64,
                        "poll_on_completion read, non-resumable IO error %d", errno);
                    errno = 0;
                    return false;
                }
            } else {
                BUS_LOG_SNPRINTF(b, 1, LOG_SENDING_REQUEST, b->udata, 64,
                    "poll_on_completion bad read size %zd", sz);
                return false;
            }
        } else {
            /* This should never happen, but I have seen it occur on OSX.
             * If we log it, reset errno, and continue, it does not appear
             * to fall into busywaiting by always returning 0. */
            BUS_LOG_SNPRINTF(b, 1, LOG_SENDING_REQUEST, b->udata, 64,
                "poll_on_completion, blocking forever returned %d, errno %d", res, errno);
            errno = 0;
        }
    }
}
Пример #26
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;
}
Пример #27
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;
}
Пример #28
0
/* ------------------------------------------------------------------------ *
 * Read as long as the system call fills the buffer and queue the data.     *
 * ------------------------------------------------------------------------ */
int io_queued_read(int fd)
{
  int ret = 0;
  size_t sz = 0;
  char buf[IO_READ_SIZE];

  syscall_errno = 0;

  do
  {
    switch(io_list[fd].type)
    {
      case FD_SOCKET:
#ifdef HAVE_SSL
        if(io_list[fd].ssl)
          ret = ssl_read(fd, buf, IO_READ_SIZE);
        else
#endif
          ret = syscall_recv(fd, buf, IO_READ_SIZE, 0);
        break;
      case FD_FILE:
      case FD_PIPE:
      default:
        ret = syscall_read(fd, buf, IO_READ_SIZE);
        break;
    }

    /* We got data, add it to the queue */
    if(ret > 0)
      sz += queue_write(&io_list[fd].recvq, buf, ret);
  }
  while(ret == IO_READ_SIZE);

  io_list[fd].status.onread = 1;
  io_list[fd].status.onwrite = 0;

/*  if(ret == 0 || (io_list[fd].type == FD_FILE && ret >= 0 && ret < IO_READ_SIZE))
  {
    io_list[fd].error = 0;
    io_list[fd].status.err = 1;

    return -1;
  }*/

#ifdef HAVE_SSL
/*  if(io_list[fd].ssl)
  {
    if(io_list[fd].error)
      return -1;
    else
      return 0;
  }
  else*/
  {
#endif
    if(ret < 0)
    {
      io_list[fd].error = syscall_errno;
      io_list[fd].status.err = 1;

      if(io_list[fd].error == EAGAIN)
      {
        io_list[fd].status.err = 0;
        return 0;
      }

      return -1;
    }
    else if(ret == 0)
    {
      io_list[fd].status.eof = 1;
    }
    else
    {
      io_list[fd].error = 0;
      io_list[fd].status.err = 0;
    }
#ifdef HAVE_SSL
  }
#endif

  return ret/* == 0 ? -1 : sz*/;
}
Пример #29
0
int getc_noecho(void)
{
  char c;
  syscall_read(stdin, &c, 1);
  return c;
}
Пример #30
0
static void
syscall_handler (struct intr_frame *f)
{
/*  printf ("system call!\n");//TODO remove
  thread_exit ();*/
  uint32_t ret_val;

  offset = f->esp;
  int sys_call = (int) next_arg();

  char *tmp; //TODO remove
  


  switch (sys_call) {
  case SYS_HALT:
    power_off();
    NOT_REACHED ();

  case SYS_EXIT:
    syscall_exit((int) next_arg());
    NOT_REACHED ();

  case SYS_EXEC:
    ret_val = exec();
    break;

  case SYS_WAIT:
    ret_val = process_wait((tid_t) next_arg());
    break;

  case SYS_CREATE:
//    printf("test\n");
//    printf("file_name: %s, size: %d\n", next_str(), next_arg());
    tmp = next_str();
    ret_val = filesys_create(tmp, next_arg());
    break;

  case SYS_REMOVE:
    ret_val = filesys_remove(next_str());
    break;

  case SYS_OPEN:
    next_str();
    break;

  case SYS_FILESIZE:
    next_arg();
    break;

  case SYS_READ:
    /* next_arg(); next_arg(); next_arg(); */
	 ret_val = syscall_read();
    break;

  case SYS_WRITE:
    //FIXME this is just a temporary function to print to console unil real call is implemented
    /*if ((int) next_arg() == STDOUT_FILENO) {
      printf("%s", (char *) next_arg());
    }*/
	 ret_val = syscall_write();
    break;

  case SYS_SEEK:

    break;

  case SYS_TELL:

    break;

  case SYS_CLOSE:

    break;

  default:
    //TODO print error message
    break;
  }
  f->eax = ret_val;
}