uint32 gft_get_by_fd(uint32 fd)
{
	if (fd >= process_get_current()->lft.entries.count)
		return INVALID_FD;

	return process_get_current()->lft.entries[fd].gfd;
}
Beispiel #2
0
//prepends cwd, normpathifys, etc
static int prepare_path(const unsigned char *pathin, unsigned char *pathout, int outsize) {
  if (pathin[0] == '/') { //do nothing?
    strncpy(pathout, pathin, outsize);
    return 0;
  }
  
  Process *p = process_get_current(0);
  
  if (!p) {
    strncpy(pathout, pathin, outsize);
    pathout[outsize-1] = 0;
    
    return -1;
  }
  
  pathout[0] = 0;
  strcat(pathout, p->working_path);
  int len = strlen(pathout);
  
  if (len == 0 && pathin[0] != '/') {
    strcat(pathout, "/");
  } else if (len != 0 && pathin[0] == '/' && pathout[len-1] == '/') {
    pathout[len-1] = 0;
  }
  
  strcat(pathout, (unsigned char*)pathin);
  normpath(pathout, outsize);
  
  return 0;
}
Beispiel #3
0
int sys_sigaction(int sig, const struct sigaction *act, struct sigaction *oact) {
	if(sig>=0 && sig<SIGNAL_MAX) {
		int index;
		index = _trans_number2index[sig];

		if(index != _SIGUNDEF) {
			struct process *cur;
			cur = process_get_current();

			if(oact != NULL) {
				*oact = cur->sig_array[index];
			}

			if(act != NULL) {
				// can't change the actions for SIGKILL or SIGSTOP
				if(sig == SIGKILL || sig == SIGSTOP) {
					return -1;
				}
				cur->sig_array[index] = *act;
			}
		}
		else {
			return -1;
		}

	}
	else {
		return -1;
	}

	return 0;
}
Beispiel #4
0
int sys_pipe2(int pipefd[2], int flags) {
	struct process *proc;
	int fdin, fdout;

	(void)flags;

	proc = process_get_current();
	for(fdin=0; fdin<PROCESS_MAX_FILE && proc->files[fdin] != NULL; fdin++);
	for(fdout=fdin+1; fdout<PROCESS_MAX_FILE && proc->files[fdout] != NULL; fdout++);

	if(fdin < PROCESS_MAX_FILE && fdout < PROCESS_MAX_FILE) {
		struct file *files[2];
		if(pipe_create(files) == 0) {
			proc->files[fdin] = files[0];
			pipefd[0] = fdin;
			proc->files[fdout] = files[1];
			pipefd[1] = fdout;

			return 0;
		}
		else {
			printk(LOG_ERR, "sys_pipe2: pipe creation failed\n");
		}
	}
	else {
		printk(LOG_WARNING, "sys_pipe2: no more file desc\n");
	}
	return -1;

}
Beispiel #5
0
int close(int fd) {
  FSFile *file = (FSFile*)fd;
  
  if (!_valid_file(fd))
    return -1;
  
  //do reference counting
  file->refs--;
  if (file->refs > 0) {
    return 0;
  }
  
  file->closed = 1;

  if (file->fs->close) {
    _lock_file(file);
    file->fs->close(file->fs, file->device, file->internalfd);
    _unlock_file(file);
  }
  
  file->magic = 0;
  
  Process *p = process_get_current(0);
  LinkNode *node;
  
  for (node=p->open_files.first; node; node=node->next) {
    if (node->data == file) {
      klist_remove(&p->open_files, node);
      kfree(node);
      break;
    }
  }

  return 0;
}
Beispiel #6
0
int open(const unsigned char *path, int modeflags) {
  unsigned char path2[MAX_PATH];
  FSInterface *fs=NULL;
  BlockDeviceIF *device=NULL;
  
  prepare_path(path, (unsigned char*)path2, sizeof(path2));
  fs_vfs_get((char*) path2, &fs, &device);
  
  FSFile *file = kmalloc(sizeof(FSFile));
  
  memset(file, 0, sizeof(*file));
  _fs_file_init(file);
  
  file->fs = fs;
  file->device = device;
  file->access = modeflags;
  
  file->internalfd = file->fs->open(file->fs, file->device, path2, strlen(path2), modeflags);
  
  if (file->internalfd < 0) {
    kfree(file);
    return -1;
  }
  
  LinkNode *node = kmalloc(sizeof(LinkNode));
  node->data = file;
  
  Process *p = process_get_current(0);
  klist_append(&p->open_files, node);
  
  return (int)file;
}
Beispiel #7
0
int sys_sigreturn() {
	struct process *cur = process_get_current();

	sched_preempt_block();
	arch_signal_restore_sigcontext(cur);
	sched_preempt_unblock();

	process_contextjmp(cur);
	return -1;
}
Beispiel #8
0
int sys_getdents(int fd, struct fixos_dirent *buf, size_t len) {
	struct process *proc;

	proc = process_get_current();
	if(fd>=0 && fd<PROCESS_MAX_FILE && proc->files[fd] != NULL) {
		return vfs_dir_getdents(proc->files[fd], buf, len);
	}
	else {
		printk(LOG_DEBUG, "sys_getdents: invalid fd\n");
		return -EBADF;
	}	
}
Beispiel #9
0
ssize_t sys_read(int fd, char *dest, int nb) {
	struct process *proc;

	proc = process_get_current();
	if(fd>=0 && fd<PROCESS_MAX_FILE && proc->files[fd] != NULL) {
		return vfs_read(proc->files[fd], dest, nb);	
	}
	else {
		printk(LOG_DEBUG, "sys_read: invalid fd\n");
		return -EBADF;
	}	
}
Beispiel #10
0
ssize_t sys_write(int fd, const char *source, int nb){
	struct process *proc;

	proc = process_get_current();
	if(fd>=0 && fd<PROCESS_MAX_FILE && proc->files[fd] != NULL) {
		return vfs_write(proc->files[fd], source, nb);	
	}
	else {
		printk(LOG_DEBUG, "sys_write: invalid fd (%d)\n", fd);
	}	

	return -EBADF;
}
Beispiel #11
0
int sys_fstat(int fd, struct stat *buf) {
	struct process *proc;

	proc = process_get_current();
	if(fd>=0 && fd<PROCESS_MAX_FILE && proc->files[fd] != NULL) {
		return vfs_fstat(proc->files[fd], buf);	
	}
	else {
		printk(LOG_DEBUG, "sys_fstat: invalid fd\n");
	}

	return -1;
}
Beispiel #12
0
int sys_lseek(int fd, off_t offset, int whence) {
	struct process *proc;

	proc = process_get_current();
	if(fd>=0 && fd<PROCESS_MAX_FILE && proc->files[fd] != NULL) {
		return vfs_lseek(proc->files[fd], offset, whence);	
	}
	else {
		printk(LOG_DEBUG, "sys_lseek: invalid fd\n");
	}

	return -1;
}
Beispiel #13
0
int sys_ioctl(int fd, int request, void *arg) {
	struct process *proc;

	proc = process_get_current();
	if(fd>=0 && fd<PROCESS_MAX_FILE && proc->files[fd] != NULL) {
		return vfs_ioctl(proc->files[fd], request, arg);	
	}
	else {
		printk(LOG_DEBUG, "sys_ioctl: invalid fd (%d)\n", fd);
	}	

	return -1;
}
Beispiel #14
0
char *getcwd(char *buf, size_t size) {
  Process *p = process_get_current(0);
  
  if (!p) 
    return NULL;
  
  krwlock_rlock(&p->environ_lock);
  
  strncpy(buf, p->working_path, size);
  buf[size-1] = 0;
  
  krwlock_unrlock(&p->environ_lock);
  
  return buf;
}
Beispiel #15
0
int sys_close(int fd) {
	struct process *proc;
	int ret;

	proc = process_get_current();
	if(fd>=0 && fd<PROCESS_MAX_FILE && proc->files[fd] != NULL) {
		ret = vfs_close(proc->files[fd]);
		proc->files[fd] = NULL;
	}
	else {
		printk(LOG_DEBUG, "sys_close: invalid fd\n");
		ret = -EBADF;
	}

	return ret;
}
Beispiel #16
0
int sys_open(const char *name, int flags) {
	struct process *proc;
	int fd;

	//printk(LOG_DEBUG, "Received sys_open :\n   ('%s', %d)\n", name, flags);
	proc = process_get_current();

	for(fd=0; fd<PROCESS_MAX_FILE && proc->files[fd] != NULL; fd++);
	if(fd < PROCESS_MAX_FILE) {
		struct inode *inode;

		// get the inode associated to file name, and open it
		inode = vfs_resolve(name);
		if(inode != NULL) {
			
			// O_CLOEXEC flag should not be seen by vfs level
			if(flags & O_CLOEXEC) {
				flags &= ~O_CLOEXEC;
				proc->fdflags[fd] = FD_CLOEXEC;
			}
			else {
				proc->fdflags[fd] = 0;
			}

			proc->files[fd] = vfs_open(inode, flags);
			if(proc->files[fd] != NULL) {
				//printk(LOG_DEBUG, "sys_open: new fd = %d\n", fd);

				// done
				return fd;
			}
			else {
				printk(LOG_DEBUG, "sys_open: unable to open ('%s', f=0x%x)\n", name, flags);
			}
		}
		else {
			printk(LOG_DEBUG, "sys_open: no such inode found\n");
		}
	}
	else {
		printk(LOG_WARNING, "sys_open: no more file desc\n");
	}
	return -1;
}
Beispiel #17
0
int chdir(char *path) {
  Process *p = process_get_current(0);
  
  if (!p) 
    return -1;
  
  DIR *dir = opendir(path);
  if (!dir) {
    e9printf("not a directory: '%s'\n", path);
    return -2; //directory doesn't exist
  }
  closedir(dir);
  
  krwlock_lock(&p->environ_lock);
  
  strncpy(p->working_path, path, sizeof(p->working_path));
  p->working_path[sizeof(p->working_path)-1] = 0;
  
  krwlock_unlock(&p->environ_lock);
  
  return 0;
}
Beispiel #18
0
void signal_deliver_pending() {
	sigset_t todeliver;
	struct process *proc;

	proc = process_get_current();
	todeliver = signal_pending(proc);

	if(todeliver != 0) {
		int atomicstate;
		int cursig;

		interrupt_atomic_save(&atomicstate);

		for(cursig=0; cursig<SIGNAL_MAX; cursig++) {
			if(sigismember(&todeliver, cursig)) {
				printk(LOG_DEBUG, "signal: try to deliver %d\n", cursig);
				try_deliver_one(proc, cursig);
			}
		}
		
		interrupt_atomic_restore(atomicstate);
	}
}
Beispiel #19
0
int sys_sigprocmask(int how, const sigset_t *set, sigset_t *oldset) {
	struct process *cur;

	cur = process_get_current();
	if(oldset != NULL) {
		*oldset = cur->sig_blocked;
	}

	if(set != NULL) {
		switch(how) {
		case SIG_SETMASK:
			cur->sig_blocked = *set & ~(SIGKILL | SIGSTOP);
			break;
		case SIG_BLOCK:
			cur->sig_blocked |= (*set & ~(SIGKILL | SIGSTOP));
			break;
		case SIG_UNBLOCK:
			cur->sig_blocked &= ~(*set);
			break;
		}
	}

	return 0;
}
void page_fault_bottom(thread_exception te)
{
	thread_exception_print(&te);
	uint32& addr = te.data[0];
	uint32& code = te.data[1];

	serial_printf("PAGE_FALUT: PROC: %u ADDRESS: %h, THREAD: %u, CODE: %h\n", process_get_current()->id, addr, thread_get_current()->id, code);

	if (process_get_current()->contract_spinlock == 1)
		PANIC("PAge fault spinlock is already reserved\n");

	spinlock_acquire(&process_get_current()->contract_spinlock);
	vm_area* p_area = vm_contract_find_area(&thread_get_current()->parent->memory_contract, addr);

	if (p_area == 0)
	{
		serial_printf("could not find address %h in memory contract", addr);
		PANIC("");		// terminate thread and process with SIGSEGV
	}

	vm_area area = *p_area;
	spinlock_release(&process_get_current()->contract_spinlock);

	// tried to acccess inaccessible page
	if ((area.flags & MMAP_PROTECTION) == MMAP_NO_ACCESS)
	{
		serial_printf("address: %h is inaccessible\n", addr);
		PANIC("");
	}

	// tried to write to read-only or inaccessible page
	if (page_fault_error_is_write(code) && (area.flags & MMAP_WRITE) != MMAP_WRITE)
	{
		serial_printf("cannot write to address: %h\n", addr);
		PANIC("");
	}

	// tried to read a write-only or inaccesible page ???what???
	/*if (!page_fault_error_is_write(code) && CHK_BIT(area.flags, MMAP_READ))
	{
		serial_printf("cannot read from address: %h", addr);
		PANIC("");
	}*/

	// if the page is present then a violation happened (we do not implement swap out/shared anonymous yet)
	if (page_fault_error_is_page_present(code) == true)
	{
		serial_printf("memory violation at address: %h with code: %h\n", addr, code);
		serial_printf("area flags: %h\n", area.flags);
		PANIC("");
	}

	// here we found out that the page is not present, so we need to allocate it properly
	if (CHK_BIT(area.flags, MMAP_PRIVATE))
	{
		if (CHK_BIT(area.flags, MMAP_ALLOC_IMMEDIATE))
		{
			// loop through all addresses and map them
			for (virtual_addr address = area.start_addr; address < area.end_addr; address += 4096)
				//if (CHK_BIT(area.flags, MMAP_ANONYMOUS))	ALLOC_IMMEDIATE works only for anonymous (imposed in mmap)
				page_fault_alloc_page(area.flags, address);
		}
		else
		{
			if (CHK_BIT(area.flags, MMAP_ANONYMOUS))
				page_fault_alloc_page(area.flags, addr & (~0xFFF));
			else
			{
				uint32 flags = page_fault_calculate_present_flags(area.flags);
				vmmngr_alloc_page_f(addr & (~0xFFF), flags);

				uint32 read_start = area.offset + ((addr - area.start_addr) / PAGE_SIZE) * PAGE_SIZE;		// file read start
				uint32 read_size = PAGE_SIZE;		// we read one page at a time (not the whole area as this may not be necessary)

				//if (read_start < area.start_addr + PAGE_SIZE)	// we are reading the first page so subtract offset from read_size
				//	read_size -= area.offset;

				serial_printf("gfd: %u, reading at mem: %h, phys: %h file: %h, size: %u\n", area.fd, addr & (~0xfff), vmmngr_get_phys_addr(addr & (~0xfff)),
					read_start, read_size);

				gfe* entry = gft_get(area.fd);
				if (entry == 0)
				{
					serial_printf("area.fd = %u", area.fd);
					PANIC("page fault gfd entry = 0");
				}

				// read one page from the file offset given at the 4KB-aligned fault address 
				if (read_file_global(area.fd, read_start, read_size, addr & (~0xFFF), VFS_CAP_READ | VFS_CAP_CACHE) != read_size)
				{
					serial_printf("read fd: %u\n", area.fd);
					PANIC("mmap anonymous file read less bytes than expected");
				}
			}
		}
	}
	else		// MMAP_SHARED
	{
		if (CHK_BIT(area.flags, MMAP_ANONYMOUS))
			PANIC("A shared area cannot be marked as anonymous yet.");
		else
		{
			// in the shared file mapping the address to read is ignored as data are read only to page cache. 
			uint32 read_start = area.offset + ((addr & (~0xfff)) - area.start_addr);
			gfe* entry = gft_get(area.fd);

			if (read_file_global(area.fd, read_start, PAGE_SIZE, -1, VFS_CAP_READ | VFS_CAP_CACHE) != PAGE_SIZE)
				PANIC("mmap shared file failed");

			virtual_addr used_cache = page_cache_get_buffer(area.fd, read_start / PAGE_SIZE);
			//serial_printf("m%h\n", used_cache);

			uint32 flags = page_fault_calculate_present_flags(area.flags);
			vmmngr_map_page(vmmngr_get_directory(), vmmngr_get_phys_addr(used_cache), addr & (~0xfff), flags/*DEFAULT_FLAGS*/);
			//serial_printf("shared mapping fd: %u, cache: %h, phys cache: %h, read: %u, addr: %h\n", area.fd, used_cache, used_cache, read_start, addr);
		}
	}
}