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_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; }