/* Execute Process */ tid_t exec (const char *cmd_line) { struct thread *child = NULL; tid_t child_pid = 0; /* Execute process with cmd_line */ child_pid = process_execute (cmd_line); /* get Process context with pid */ child = get_child_process (child_pid); if (!child) return -1; /* Wait for loading child process */ if (child->thread_loaded == NO_LOAD) { sema_down(&child->sema_load); } /* Return error for exception */ if (child->thread_loaded == FAIL_LOAD) return -1; /* Return pid of child process */ return child_pid; }
tid_t exec(const char* cmd_line) { tid_t tid; struct thread* t; tid = process_execute(cmd_line); if( tid == TID_ERROR ) return -1; t = get_child_process(tid); if( t-> load_success == 0 ) return (tid_t)-1; else return tid; }
/* create child process and wait until childprocess is loaded */ tid_t exec(const char *cmd_name) { struct thread *child_process; tid_t pid; pid = process_execute(cmd_name); child_process = get_child_process(pid); /* wait child process */ sema_down(&(child_process->load_semaphore)); if(child_process->load_success==true) return pid; else { return -1; } }
static void syscall_handler (struct intr_frame *f) { uint32_t *p = f->esp; check_ptr(p); switch (*(int *)p) { /* Halt the operating system. IN : void OUT: void */ case SYS_HALT: { shutdown_power_off(); break; } /* Terminate this process. IN : int status OUT: void */ case SYS_EXIT: { check_ptr(p + 1); int status = *(int *)(p + 1); exit(status); break; } /* Start another process. IN : const char *file OUT: pid_t */ case SYS_EXEC: { check_string(p + 1); // f->eax = process_execute(*(char **)(p + 1)); pid_t pid = process_execute(*(char **)(p + 1)); struct child_process *cp = get_child_process(pid); if(cp->load == LOAD_SUCCESS) f->eax = pid; else if(cp->load == LOAD_FAIL) f->eax = -1; break; } /* Wait for a child process to die. IN : pid_t OUT: int */ case SYS_WAIT: { check_ptr(p + 1); f->eax = process_wait(*(tid_t *)(p + 1)); break; } /* Create a file. IN :const char *file, unsigned initial_size OUT:bool */ case SYS_CREATE: { check_string(p + 1); check_ptr(p + 2); if(*(char**)(p+1)==NULL||*(int *)(p+1)>=PHYS_BASE|| pagedir_get_page(thread_current()->pagedir, (const void *)*(p+1)) == NULL) exit(-1); f->eax = filesys_create(*(const char **)(p + 1), *(off_t *)(p + 2)); break; } /* Delete a file. IN: const char *file OUT: bool */ case SYS_REMOVE: { check_string(p + 1); if(*(char**)(p+1)==NULL||*(int *)(p+1)>=PHYS_BASE|| pagedir_get_page(thread_current()->pagedir, (const void *)*(p+1)) == NULL) exit(-1); f->eax = filesys_remove(*(char**)(p + 1)); break; } /* Open a file. IN: const char *file OUT: int */ case SYS_OPEN: { check_string(p + 1); struct file *file = filesys_open(*(char**)(p + 1)); if (file == NULL) { f->eax = -1; break; } struct file_desc *desc = malloc(sizeof(struct file_desc)); desc->file = file; desc->fd = thread_current()->fd; thread_current()->fd++; list_push_back(&thread_current()->file_list, &desc->elem); f->eax = desc->fd; break; } /* Obtain a file's size. IN: int fd OUT: int */ case SYS_FILESIZE: { check_ptr(p + 1); int fd = *(p + 1); struct file *file = process_get_file(fd); if (file == NULL) { f->eax = FILE_ERROR; } else { f->eax = file_length(file); } break; } /* Read from a file. IN: int fd, void *buffer, unsigned length OUT: int */ case SYS_READ: { check_ptr(p + 1); check_ptr(p + 2); check_ptr(p + 3); check_buffer(p + 2, *(p + 3)); int fd = *(int *)(p + 1); void *buffer = *(char**)(p + 2); unsigned length = *(unsigned *)(p + 3); //read from keyboard. Fd 0 reads from keyboard using input_getc(): one each time. if (fd == STDIN_FILENO) { uint8_t *into_buffer = (uint8_t *) buffer; unsigned i; for (i = 0; i < length; i++) { into_buffer[i] = input_getc(); } f->eax = length; } else { //read from file into buffer struct file *file = process_get_file(fd); //return -1 if file couldn't be read. if (file == NULL) { f->eax = FILE_ERROR; //-1 } else { int bytes = file_read(file, buffer, length); f->eax = bytes; } } break; } /* Write to a file. IN: int fd, const void *buffer, unsigned length OUT: int */ case SYS_WRITE: { check_ptr(p + 1); check_ptr(p + 2); check_ptr(p + 3); check_buffer(p + 2, *(p + 3)); int fd = *(int *)(p + 1); void *buffer = *(char**)(p + 2); unsigned length = *(off_t *)(p + 3); if (length <= 0) { f->eax = 0; break; } //Fd=1(STDOUT_FILENO) writes to the console. if (fd == STDOUT_FILENO) { putbuf(buffer, length); f->eax = length; } else { // return file by file descriptor. struct file *file = process_get_file(fd); if (file == NULL) { f->eax = FILE_ERROR; //-1 } else { int bytes = file_write(file, buffer, length); f->eax = bytes; } } break; } /* Change position in a file. IN: int fd, unsigned position OUT: void */ case SYS_SEEK: { check_ptr(p + 1); check_ptr(p + 2); int fd = *(int *)(p+1); unsigned position = *(unsigned *)(p+2); struct file *file = process_get_file(fd); if(file != NULL) { file_seek(file, position); } break; } /* Report current position in a file. IN: int fd OUT: unsigned */ case SYS_TELL: { check_ptr(p + 1); int fd = *(int *)(p+1); struct file *file = process_get_file(fd); if(file != NULL) { f->eax = file_tell(file); } else f->eax = FILE_ERROR; //-1 break; } /* Close a file. IN: int fd OUT: void */ case SYS_CLOSE: { check_ptr(p+1); int fd = *(int*)(p+1); struct thread *t = thread_current(); struct list_elem *next, *e = list_begin(&t->file_list); while (e != list_end (&t->file_list)) { next = list_next(e); struct file_desc *fl = list_entry (e, struct file_desc, elem); if (fd == fl->fd) { file_close(fl->file); list_remove(&fl->elem); free(fl); break; } e = next; } break; } default: break; } }