int file_seek(int fd, off_t pos, int whence) { struct stat __stat, *stat = &__stat; int ret; struct file *file; if ((ret = fd2file(fd, &file)) != 0) { return ret; } filemap_acquire(file); switch (whence) { case LSEEK_SET: break; case LSEEK_CUR: pos += file->pos; break; case LSEEK_END: if ((ret = vop_fstat(file->node, stat)) == 0) { pos += stat->st_size; } break; default: ret = -E_INVAL; } if (ret == 0) { if ((ret = vop_tryseek(file->node, pos)) == 0) { file->pos = pos; } } filemap_release(file); return ret; }
int file_fstat(int fd, struct stat *stat) { int ret; struct file *file; if ((ret = fd2file(fd, &file)) != 0) { return ret; } filemap_acquire(file); ret = vop_fstat(file->node, stat); filemap_release(file); return ret; }
int file_open(char *path, uint32_t open_flags) { bool readable = 0, writable = 0; switch (open_flags & O_ACCMODE) { case O_RDONLY: readable = 1; break; case O_WRONLY: writable = 1; break; case O_RDWR: readable = writable = 1; break; default: return -E_INVAL; } int ret; struct file *file; if ((ret = filemap_alloc(NO_FD, &file)) != 0) { return ret; } struct inode *node; if ((ret = vfs_open(path, open_flags, &node)) != 0) { filemap_free(file); return ret; } file->pos = 0; if (open_flags & O_APPEND) { struct stat __stat, *stat = &__stat; if ((ret = vop_fstat(node, stat)) != 0) { vfs_close(node); filemap_free(file); return ret; } file->pos = stat->st_size; } file->node = node; file->readable = readable; file->writable = writable; filemap_open(file); return file->fd; }
int file_open(char *path, uint32_t open_flags) { bool readable = 0, writable = 0; switch (open_flags & O_ACCMODE) { case O_RDONLY: readable = 1; break; case O_WRONLY: writable = 1; break; case O_RDWR: readable = writable = 1; break; default: return -E_INVAL; } //TODO: Implement other open flags. //Try to allocate a new kernel struct file object. struct file *file = kernel_file_pool_allocate(); file_init(file); if(file == NULL) { return -E_NO_MEM; } file->readable = readable; file->writable = writable; //Allocate a new file descriptor struct file_desc_table *desc_table = fs_get_desc_table(current->fs_struct); int fd = file_desc_table_get_unused(desc_table); if(fd < 0) { return -E_MFILE; } int ret; //Allocate a new inode for the kernel file struct inode *node; ret = vfs_open(path, open_flags, &node); if (ret != 0) { kernel_file_pool_free(file); return ret; } //Initialize file state file->pos = 0; if (open_flags & O_APPEND) { struct stat __stat, *stat = &__stat; if ((ret = vop_fstat(node, stat)) != 0) { vfs_close(node); kernel_file_pool_free(file); return ret; } file->pos = stat->st_size; } //Associate the file descriptor with kernel file object file_desc_table_associate(desc_table, fd, file); file->node = node; file->io_flags = 0; return fd; }