int sys_read (uint_t fd, void *buf, size_t count) { ssize_t err; struct thread_s *this; struct task_s *task; struct vfs_file_s *file; this = current_thread; task = current_task; if((fd >= CONFIG_TASK_FILE_MAX_NR) || (task_fd_lookup(task,fd) == NULL)) { this->info.errno = EBADFD; return -1; } file = task_fd_lookup(task,fd); if((err = vfs_read(file, (uint8_t*)buf, count)) < 0) { this->info.errno = -err; printk(INFO, "INFO: sys_read: Error %d\n", this->info.errno); return -1; } return err; }
int sys_readdir (uint_t fd, struct vfs_dirent_s *dirent) { error_t err; struct task_s *task; struct thread_s *this; struct vfs_file_s *file; task = current_task; this = current_thread; if((dirent == NULL) || (fd >= CONFIG_TASK_FILE_MAX_NR) || (task_fd_lookup(task,fd) == NULL)) { this->info.errno = EBADFD; return -1; } file = task_fd_lookup(task,fd); if((err = vfs_readdir(file, dirent))) { this->info.errno = (err < 0) ? -err : err; return -1; } return 0; }
int sys_stat(char *pathname, struct vfs_stat_s *buff, int fd) { struct thread_s *this; register error_t err = 0; struct vfs_file_s *file; struct vfs_node_s *node; struct task_s *task; this = current_thread; task = current_task; if((buff == NULL) || ((pathname == NULL) && (fd == -1))) { this->info.errno = EINVAL; return -1; } if((uint_t)buff >= CONFIG_KERNEL_OFFSET) { this->info.errno = EPERM; return -1; } if(pathname == NULL) { if((fd >= CONFIG_TASK_FILE_MAX_NR) || (task_fd_lookup(task,fd) == NULL)) return EBADFD; file = task_fd_lookup(task,fd); node = file->f_node; err = vfs_stat(task->vfs_cwd, NULL, &node); } else { node = NULL; rwlock_rdlock(&task->cwd_lock); err = vfs_stat(task->vfs_cwd, pathname, &node); rwlock_unlock(&task->cwd_lock); } if(err) goto SYS_STAT_ERR; err = cpu_uspace_copy(buff, &node->n_stat, sizeof(node->n_stat)); if(err == 0) return 0; SYS_STAT_ERR: if(pathname == NULL) vfs_node_down_atomic(node); this->info.errno = err; return -1; }
int sys_close (uint_t fd) { register struct task_s *task; register struct thread_s *this; struct vfs_file_s *file; error_t err; file = NULL; this = current_thread; task = current_task; if((fd >= CONFIG_TASK_FILE_MAX_NR) || (task_fd_lookup(task, fd, &file))) { this->info.errno = EBADFD; return -1; } if((err = vfs_close(file, NULL))) { this->info.errno = err; return -1; } task_fd_put(task, fd); cpu_wbflush(); return 0; }
int sys_stat(char *pathname, struct vfs_stat_s *buff, int fd) { struct thread_s *this; register error_t err = 0; struct vfs_file_s *file; struct ku_obj ku_path; struct task_s *task; file = NULL; this = current_thread; task = current_task; if((buff == NULL) || ((pathname == NULL) && (fd == -1))) { this->info.errno = EINVAL; return -1; } if(NOT_IN_USPACE((uint_t)buff)) { this->info.errno = EPERM; return -1; } if(pathname == NULL) { if((fd >= CONFIG_TASK_FILE_MAX_NR) || (task_fd_lookup(task, fd, &file))) return EBADFD; err = vfs_stat(&task->vfs_cwd, NULL, buff, file); } else { KU_BUFF(ku_path, pathname); rwlock_rdlock(&task->cwd_lock); err = vfs_stat(&task->vfs_cwd, &ku_path, buff, NULL); rwlock_unlock(&task->cwd_lock); } this->info.errno = err; return -1; }
int sys_mmap(mmap_attr_t *mattr) { error_t err; uint_t count; struct thread_s *this; struct task_s *task; struct vfs_file_s *file; mmap_attr_t attr; int retval; this = current_thread; task = this->task; err = EINVAL; file = NULL; if((err = cpu_uspace_copy(&attr, mattr, sizeof(mmap_attr_t)))) { printk(INFO, "%s: failed, copying from uspace @%x\n", __FUNCTION__, mattr); this->info.errno = EFAULT; return (int)VM_FAILED; } if((attr.flags & VM_REG_HEAP) || ((attr.flags & VM_REG_PVSH) == VM_REG_PVSH) || ((attr.flags & VM_REG_PVSH) == 0) || (attr.length == 0) || (attr.offset & PMM_PAGE_MASK) || ((attr.addr != NULL) && (((uint_t)attr.addr & PMM_PAGE_MASK) || ((attr.length + (uint_t)attr.addr) > CONFIG_USR_LIMIT)))) { printk(INFO, "%s: failed, we don't like flags (%x), length (%d), or addr (%x)\n", __FUNCTION__, attr.flags, attr.length, attr.addr); this->info.errno = EINVAL; return (int)VM_FAILED; } if(attr.flags & VM_REG_ANON) { attr.offset = 0; attr.addr = (attr.flags & VM_REG_FIXED) ? attr.addr : NULL; } else { if((attr.fd > CONFIG_TASK_FILE_MAX_NR) || (task_fd_lookup(task,attr.fd) == NULL)) { printk(INFO, "%s: failed, bad file descriptor (%d)\n", __FUNCTION__, attr.fd); this->info.errno = EBADFD; return (int)VM_FAILED; } /* FIXEME: possible concurent delete of file from another bugy thread closing it */ file = task_fd_lookup(task,attr.fd); atomic_add(&file->f_count, 1); if((attr.offset + attr.length) > file->f_node->n_size) { printk(INFO, "%s: failed, offset (%d) + len (%d) >= file's size (%d)\n", __FUNCTION__, attr.offset, attr.length, file->f_node->n_size); this->info.errno = ERANGE; goto SYS_MMAP_FILE_ERR; } if(((attr.prot & VM_REG_RD) && !(VFS_IS(file->f_flags, VFS_O_RDONLY))) || ((attr.prot & VM_REG_WR) && !(VFS_IS(file->f_flags, VFS_O_WRONLY))) || ((attr.prot & VM_REG_WR) && (VFS_IS(file->f_flags, VFS_O_APPEND))))// || //(!(attr.prot & VM_REG_RD) && (attr.flags & VM_REG_PRIVATE))) { printk(INFO, "%s: failed, EACCES prot (%x), f_flags (%x)\n", __FUNCTION__, attr.prot, file->f_flags); this->info.errno = EACCES; goto SYS_MMAP_FILE_ERR; } } retval = (int) vmm_mmap(task, file, attr.addr, attr.length, attr.prot, attr.flags, attr.offset); if((retval != (int)VM_FAILED) || (attr.flags & VM_REG_ANON)) return retval; SYS_MMAP_FILE_ERR: printk(INFO, "%s: Failed, Droping file count (%d)\n", __FUNCTION__, file->f_count); vfs_close(file, &count); if(count == 1) task_fd_put(task, attr.fd); return (int)VM_FAILED; }