/* read file */ int read(int fd, void *buffer, unsigned size) { int read_size = 0; struct file *current_file; char *read_buffer = (char *)buffer; lock_acquire(&file_lock); if(fd == 0) /* stdin */ { read_buffer[read_size]=input_getc(); while(read_buffer[read_size] != '\n' && read_size < size) { read_size++; read_buffer[read_size]=input_getc(); } read_buffer[read_size]='\0'; } else { current_file = process_get_file(fd); if(current_file != NULL) { read_size = file_read(current_file,buffer,size); } } lock_release(&file_lock); return read_size; }
/* write file */ int write(int fd, void *buffer, unsigned size) { int write_size = 0; struct file *current_file; struct inode *inode; lock_acquire(&file_lock); if(fd == 1) /* stdout */ { putbuf((const char *)buffer,size); write_size = size; } else { current_file = process_get_file(fd); inode = file_get_inode(current_file); /* if file is directory, return -1 */ if( inode_is_dir(inode) == true){ lock_release(&file_lock); return -1; } if(current_file != NULL) write_size = file_write(current_file,(const void *)buffer,size); } lock_release(&file_lock); return write_size; }
int write (int fd, const void *buffer, unsigned size) { if (fd == STDIN_FILENO) return -1; if (fd == STDOUT_FILENO) { putbuf ((const char*)buffer, size); return size; } lock_acquire (&filesys_lock); struct file *f = process_get_file (fd); if (!f) { lock_release (&filesys_lock); return -1; } int bytes = file_write (f, buffer, size); lock_release (&filesys_lock); return bytes; }
unsigned tell(int fd) { struct file* f = process_get_file(fd); if( f == NULL ) return (unsigned)-1; return (unsigned)file_tell(f); }
/* read directory */ bool sys_readdir(int fd, char *name) { bool result = false; struct file *pfile = process_get_file(fd); struct inode *inode = file_get_inode(pfile); struct dir *dir; int offset = 0; char entry[100]; if(pfile != NULL) { /* if file is not directory, return false */ if(inode_is_dir(inode) == false ) return result; dir = dir_open(inode); /* read directory and store to name */ while(dir_readdir(dir, entry) == true) { /* read directory except . and .. */ if( strcmp(entry,".") == 0 || strcmp(entry,"..") == 0 ) continue; /* copy entry to name */ strlcpy(&name[offset], entry, strlen(entry)+1); offset = strlen(entry) + 1; } result = true; } return true; }
int read (int fd, void *buffer, unsigned size) { unsigned i = 0; if (fd == STDOUT_FILENO) return -1; if (fd == STDIN_FILENO) { uint8_t *local_buffer = (uint8_t*) buffer; for (i = 0; i < size; i++) { local_buffer[i] = input_getc(); } return size; } lock_acquire (&filesys_lock); struct file *f = process_get_file (fd); if (!f) { lock_release (&filesys_lock); return -1; } int bytes = file_read (f, buffer, size); lock_release (&filesys_lock); return bytes; }
/* * write to either file or console */ void syscall_write (struct intr_frame *f) { const int argz = 3; int args[argz]; syscall_get_args(f,args,argz); syscall_check_arg_buffer_or_exit((const void *)args[1], (unsigned) args[2]); args[1] = syscall_user_to_kernel_vaddr((const void*) args[1]); if(args[0] == STDOUT_FILENO) { putbuf ((const void*) args[1], (size_t) args[2]); f->eax = (int) args[2]; return; } lock_acquire (&flock); struct file *file = process_get_file (args[0]); if (file == NULL) { f->eax = -1; lock_release (&flock); return; } f->eax = file_write (file, (const void*) args[1], (off_t) args[2] ); lock_release (&flock); }
void seek(int fd,unsigned position) { struct file* f = process_get_file(fd); if( f == NULL ) return; file_seek(f,position); return; }
int filesize (int fd) { struct file *f = process_get_file (fd); if (!f) return -1; return file_length(f); }
unsigned tell (int fd) { struct file *f = process_get_file (fd); if (!f) return -1; return file_tell(f); }
/* move file offset */ void seek(int fd, unsigned position) { struct file *current_file; current_file = process_get_file(fd); if(current_file != NULL) file_seek(current_file,position); }
/* close file */ void close(int fd) { struct file *current_file; current_file = process_get_file(fd); if(current_file != NULL) { file_close(current_file); thread_current()->file_descriptor[fd]=NULL; } }
/* return file offset */ unsigned tell(int fd) { struct file *current_file; current_file = process_get_file(fd); unsigned offset = 0; if(current_file != NULL) offset = file_tell(current_file); return offset; }
/* if file is directory, return true */ bool sys_isdir(int fd) { bool result = false; struct file *pfile; /* get file */ pfile = process_get_file(fd); if(pfile != NULL) { result = inode_is_dir(file_get_inode(pfile)); } return result; }
/* get ondisk block sector */ uint32_t sys_inumber(int fd) { struct file *file = process_get_file(fd); struct inode *inode; if(file != NULL) { /* return ondisk block sector number */ inode = file_get_inode(file); return inode_get_inumber(inode); } /* if file is not exist, return -1*/ return -1; }
/* return filesize */ int filesize(int fd) { int file_size; struct file *current_file; current_file = process_get_file(fd); if(current_file != NULL) { file_size = file_length(current_file); return file_size; } else { return -1; } }
/* write file */ int write(int fd, void *buffer, unsigned size) { int write_size = 0; struct file *current_file; lock_acquire(&file_lock); if(fd == 1) /* stdout */ { putbuf((const char *)buffer,size); write_size = size; } else { current_file = process_get_file(fd); if(current_file != NULL) write_size = file_write(current_file,(const void *)buffer,size); } lock_release(&file_lock); return write_size; }
int mmap(int fd, void *addr) { struct thread *t = thread_current(); struct mmap_file* mmap_f= malloc(sizeof(struct mmap_file)); // mmap_file allocate struct file *fp1 = process_get_file(fd); // get file for fd if(fp1 == NULL) return -1; if( !is_user_vaddr(addr)|| addr < (void *)0x08048000 || ((uint32_t)addr % PGSIZE)!= 0)return -1; // only on user address space, set address to aligned pagesize struct file *fp2 = file_reopen(fp1); // fail for reopening if(fp2 == NULL || file_length(fp1) == 0) return -1; if(mmap_f != NULL){ // fail for allocate space for mmap_file t->mapid++; mmap_f->file = fp2; mmap_f->mapid = t->mapid; list_init(&mmap_f->vme_list); }else return -1; int32_t offset = 0; uint32_t read_bytes = file_length(fp2); // to read the number of bytes uint32_t page_read_bytes; uint32_t page_zero_bytes; while(read_bytes > 0) { page_read_bytes = read_bytes < PGSIZE ? read_bytes : PGSIZE; // over PGSIZE 4096 page_zero_bytes = PGSIZE - page_read_bytes; // add_mmap_to_page struct vm_entry *entry = malloc(sizeof(struct vm_entry)); if(entry == NULL)return -1; entry->file = fp2; // vme_entry initialize entry->offset = offset; entry->vaddr = addr; entry->read_bytes = page_read_bytes; entry->zero_bytes = page_zero_bytes; entry->is_loaded = false; entry->type = VM_FILE; entry->writable = true; list_push_back(&mmap_f->vme_list,&entry->mmap_elem); // to push element to (mmap_file`s member) vme_list if(!insert_vme(&t->vm,entry))return -1; read_bytes -= page_read_bytes; // if read_bytes > PGSIZE -> decrease PGSIZE offset += page_read_bytes; addr += PGSIZE; } list_push_back(&t->mmap_list,&mmap_f->elem); //to push element to( struct thread`s member )mmap_list return t->mapid; }
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; } }