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 linux_devfile_write(int fd, void *base, size_t len, size_t * copied_store) { int ret = -E_INVAL; struct file *file; /* use 8byte int, in case of 64bit off_t * config in linux kernel */ int64_t offset; if ((ret = fd2file(fd, &file)) != 0) { return 0; } if (!file->writable) { return -E_INVAL; } filemap_acquire(file); offset = file->pos; struct device *dev = vop_info(file->node, device); assert(dev); ret = dev->d_linux_write(dev, base, len, (size_t *) & offset); if (ret >= 0) { *copied_store = (size_t) ret; file->pos += ret; ret = 0; } filemap_release(file); return ret; }
// read file int file_read(int fd, void *base, size_t len, size_t *copied_store) { cprintf("file_read begin\n"); int ret; struct file *file; *copied_store = 0; if ((ret = fd2file(fd, &file)) != 0) { return ret; } if (!file->readable) { return -E_INVAL; } fd_array_acquire(file); cprintf("file_read file acquired\n"); struct iobuf __iob, *iob = iobuf_init(&__iob, base, len, file->pos); ret = vop_read(file->node, iob); size_t copied = iobuf_used(iob); if (file->status == FD_OPENED) { file->pos += copied; } *copied_store = copied; fd_array_release(file); cprintf("file_read file released\n"); cprintf("file_read end\n"); return ret; }
int file_dup(int fd1, int fd2) { int ret; struct file *file; //If fd1 is invalid, return -E_BADF. if ((ret = fd2file(fd1, &file)) != 0) { return ret; } //fd1 and fd2 cannot be the same if (fd1 == fd2) { return -E_INVAL; } struct file_desc_table *desc_table = fs_get_desc_table(current->fs_struct); //If fd2 is an opened file, close it first. This is what dup2 on linux does. struct file *file2 = file_desc_table_get_file(desc_table, fd2); if(file2 != NULL) { file_desc_table_dissociate(desc_table, fd2); } //If fd2 is NO_FD, a new fd will be assigned. if (fd2 == NO_FD) { fd2 = file_desc_table_get_unused(desc_table); } //Now let fd2 become a duplication for fd1. file_desc_table_associate(desc_table, fd2, file); //fd2 is returned. return fd2; }
int file_close(int fd) { int ret; struct file *file; if ((ret = fd2file(fd, &file)) != 0) { return ret; } filemap_close(file); return 0; }
/* linux devfile adaptor */ bool __is_linux_devfile(int fd) { int ret = -E_INVAL; struct file *file; if ((ret = fd2file(fd, &file)) != 0) { return 0; } if (file->node && check_inode_type(file->node, device) && dev_is_linux_dev(vop_info(file->node, device))) return 1; return 0; }
int file_fsync(int fd) { int ret; struct file *file; if ((ret = fd2file(fd, &file)) != 0) { return ret; } filemap_acquire(file); ret = vop_fsync(file->node); 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_dup(int fd1, int fd2) { int ret; struct file *file1, *file2; if ((ret = fd2file(fd1, &file1)) != 0) { return ret; } if ((ret = filemap_alloc(fd2, &file2)) != 0) { return ret; } filemap_dup(file2, file1); return file2->fd; }
int linux_devfile_ioctl(int fd, unsigned int cmd, unsigned long arg) { int ret = -E_INVAL; struct file *file; if ((ret = fd2file(fd, &file)) != 0) { return 0; } filemap_acquire(file); struct device *dev = vop_info(file->node, device); assert(dev); ret = dev->d_linux_ioctl(dev, cmd, arg); filemap_release(file); return ret; }
void *linux_devfile_mmap2(void *addr, size_t len, int prot, int flags, int fd, size_t pgoff) { int ret = -E_INVAL; struct file *file; if ((ret = fd2file(fd, &file)) != 0) { return NULL; } filemap_acquire(file); struct device *dev = vop_info(file->node, device); assert(dev); void* r = dev->d_linux_mmap(dev, addr, len, prot, flags, pgoff); filemap_release(file); return r; }
//TODO: Rewrite this function. int file_close(int fd) { struct file_desc_table *desc_table = fs_get_desc_table(current->fs_struct); if(file_desc_table_get_file(desc_table, fd) == NULL) { return -E_BADF; } int ret; struct file *file; if ((ret = fd2file(fd, &file)) != 0) { return ret; } file_desc_table_dissociate(desc_table, fd); return 0; }
bool file_testfd(int fd, bool readable, bool writable) { int ret; struct file *file; if ((ret = fd2file(fd, &file)) != 0) { return 0; } if (readable && !file->readable) { return 0; } if (writable && !file->writable) { return 0; } return 1; }
int file_getdirentry(int fd, struct dirent *direntp) { int ret; struct file *file; if ((ret = fd2file(fd, &file)) != 0) { return ret; } filemap_acquire(file); struct iobuf __iob, *iob = iobuf_init(&__iob, direntp->d_name, sizeof(direntp->d_name), direntp->d_off); if ((ret = vop_getdirentry(file->node, iob)) == 0) { direntp->d_off += iobuf_used(iob); } filemap_release(file); return ret; }
int file_getdirentry(int fd, struct dirent *direntp) { int ret; struct file *file; if ((ret = fd2file(fd, &file)) != 0) { return ret; } filemap_acquire(file); // kprintf("%s %s %d\n", __FILE__, __func__, __LINE__); struct iobuf __iob, *iob = iobuf_init(&__iob, direntp->name, sizeof(direntp->name), direntp->offset); if ((ret = vop_getdirentry(file->node, iob)) == 0) { direntp->offset += iobuf_used(iob); } filemap_release(file); return ret; }
int file_write(int fd, void *base, size_t len, size_t * copied_store) { int ret; struct file *file; *copied_store = 0; if ((ret = fd2file(fd, &file)) != 0) { return ret; } if (!file->writable) { return -E_INVAL; } filemap_acquire(file); struct iobuf __iob, *iob = iobuf_init(&__iob, base, len, file->pos); ret = vop_write(file->node, iob, file->io_flags); size_t copied = iobuf_used(iob); file->pos += copied; *copied_store = copied; filemap_release(file); return ret; }