Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
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;
}
Пример #4
0
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;
}
Пример #5
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;
}
Пример #6
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;
}