예제 #1
0
int
html_load_file(struct html_output *output, int fd)
{
	filestat_t sb;
	size_t size = 0;
	void *p = MAP_FAILED;
	char *buf = NULL;
	int ret = -1;

	if (fstat(fd, &sb)) {
		perror("open");
		goto error;
	}
	if (!S_ISREG(sb.st_mode)) {
		g_warning("not a regular file");
		goto error;
	}
	if (sb.st_size < 0 || UNSIGNED(sb.st_size) >= (size_t)-1) {
		g_warning("file is too large");
		goto error;
	}
	size = sb.st_size;

#ifdef HAS_MMAP
	/* FIXME: Not available on MINGW! Replace with vmm_loadfile() */
	p = vmm_mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0);
	if (MAP_FAILED == p) {
		perror("open");
		goto error;
	}
	fd_forget_and_close(&fd);
#else
	{
		size_t left = size;

		buf = g_malloc(size);
		p = buf;

		while (left > 0) {
			ssize_t n = read(fd, &buf[size - left], left);
			if ((ssize_t) -1 == n || 0 == n)
				goto error;
			left -= n;
		}
	}
#endif

	ret = html_load_memory(output, array_init(p, size));

error:
	fd_forget_and_close(&fd);
	G_FREE_NULL(buf);

#ifdef HAS_MMAP
	if (MAP_FAILED != p) {
		vmm_munmap(p, size);
	}
#endif	/* HAS_MMAP*/

	return ret;
}
예제 #2
0
파일: elf.c 프로젝트: Masshat/almos
static error_t elf_segments_load(struct vfs_file_s *file,
				 Elf32_Ehdr *e_header, 
				 Elf32_Phdr *p_entry,
				 struct task_s *task)
				
{
	register error_t err;
	register uint_t index;
	register size_t size;
	register uint_t start;
	register uint_t limit;
	uint_t proto;
	uint_t flags;

	for(index = 0; index < e_header->e_phnum; index++, p_entry++) 
	{   
		if(p_entry->p_type != PT_LOAD)
			continue;
    
#if 1
		if((p_entry->p_vaddr < USR_OFFSET) || (p_entry->p_vaddr >= USR_LIMIT))
		{
			err = EPERM;
			printk(ERROR, "\nERROR: %s: p_vaddr %x, index %d [ EPERM ]\n",
			       __FUNCTION__, 
			       p_entry->p_vaddr, 
			       index);

			return err;
		}
#endif
    
		if((err=vfs_lseek(file, p_entry->p_offset, VFS_SEEK_SET, NULL)))
		{
			printk(ERROR, "\nERROR: %s: faild to localise segment @index %d\n", 
			       __FUNCTION__, 
			       index);

			return err;
		}

		size  = 0;
		start = p_entry->p_vaddr;
		limit = p_entry->p_vaddr + p_entry->p_memsz;
    
		if((start & PMM_PAGE_MASK) || (limit & PMM_PAGE_MASK))
			return EACCES;

		if(task->vmm.text_start == 0)
		{
			proto                = VM_REG_RD | VM_REG_EX;
			flags                = VM_REG_SHARED | VM_REG_FIXED | VM_REG_INST;
			task->vmm.text_start = start;
			task->vmm.text_end   = limit;

			printk(INFO, "INFO: %s: Text <0x%x - 0x%x>\n", 
			       __FUNCTION__, 
			       start, 
			       limit);
		}
		else
		{
			if(task->vmm.data_start != 0)
				continue;
      
			proto                  = VM_REG_RD | VM_REG_WR;
			flags                  = VM_REG_PRIVATE | VM_REG_FIXED;
			task->vmm.data_start   = start;
			task->vmm.data_end     = limit;
			task->vmm.heap_start   = limit;
			task->vmm.heap_current = limit;

			printk(INFO, "INFO: %s: Data <0x%x - 0x%x>\n", 
			       __FUNCTION__, 
			       start, 
			       limit);
		}

		err = (error_t) vmm_mmap(task, 
					 file, 
					 (void*)start, 
					 limit - start, 
					 proto, 
					 flags,
					 p_entry->p_offset);

		if(err == (error_t)VM_FAILED)
		{
			printk(WARNING,"WARNING: %s: Faild to map segment <0x%x - 0x%x>, proto %x, file name %x\n",
			       __FUNCTION__, 
			       start, 
			       limit, 
			       proto, 
			       file->f_node->n_name);

			return current_thread->info.errno;
		}

		atomic_add(&file->f_count, 1);
	}

	return 0;
}
예제 #3
0
파일: sys_mmap.c 프로젝트: Masshat/almos
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;
}