summaryrefslogblamecommitdiff
path: root/src/kernel/vfs/node.cpp
blob: c517aaecdb238cefe1eca9846a3b48aa9968e0d0 (plain) (tree)
1
2
3
4

                 

                                         












                                      
                                          


                           



                                         

 
                                      
                        
                        









                                                           
                                            























                                                         
                                  























































                                                               



                                                      
 
#include "node.h"
#include "vdir.h"

int node::open(process *proc, int mode) {
	return 0;	// ok
}

int node::stat(file_info *info) {
	info->type = type;
	info->dev_type = dev_type;
	info->mode = mode;
	info->uid = uid;
	info->gid = gid;
	info->size = this->get_size();
	return 0;
}

node *root = 0, *dot_dev = 0, *dot_ui = 0;

void vfs_setup() {
	root = new vdir(0);
	dot_dev = new vdir(root);
	root->add_child(".dev", dot_dev);
	dot_ui = new vdir(root);
	root->add_child(".ui", dot_ui);
}

node* vfs_find(node* root, char* fn) {
	node* el = root;
	char *path = fn;
	char *member = path;
	
	while (*path != 0 && el != 0) {
		if (*path == '/') {
			if (member == path) {
				member++;
				path++;
			} else {
				*path = 0;
				el = el->get_child(member);
				*path = '/';
				path++;
				member = path;
			}
		} else {
			path++;
		}
	}
	if (el != 0 && member != path) {
		el = el->get_child(member);
	}

	return el;
}

node* vfs_read_fd(FILE d) {
	return current_process->fd.at(d);
}

// Syscalls

static FILE i_open(node* r, char* filename, int mode) {
	node* f = vfs_find(r, filename);
	if (f == 0) return E_NOT_FOUND;
	//TODO : different actions depending on open mode
	//TODO : permission checks
	int e = f->open(current_process, mode);
	if (e != 0) return e;
	return current_process->fd.add(f);
}

FILE open(char* filename, int mode) {
	return i_open(root, filename, mode);
}

FILE open_relative(FILE root, char* filename, int mode) {
	node* n = vfs_read_fd(root);
	if (n == 0) return E_INVALID_FD;
	return i_open(n, filename, mode);
}

int stat(char* filename, file_info *info) {
	node *f = vfs_find(root, filename);
	if (f == 0) return E_NOT_FOUND;
	return f->stat(info);
}

int stat_relative(FILE root, char* filename, file_info *info) {
	node *r = vfs_read_fd(root);
	if (r == 0) return E_INVALID_FD;
	node *f = vfs_find(r, filename);
	if (f == 0) return E_NOT_FOUND;
	return f->stat(info);
}

int statf(FILE file, file_info *info) {
	node *f = vfs_read_fd(file);
	if (f == 0) return E_INVALID_FD;
	return f->stat(info);
}

void close(FILE file) {
	node *f = vfs_read_fd(file);
	if (f != 0) {
		f->close(current_process);
		current_process->fd.set(file, 0);
	}
}

int read(FILE file, size_t offset, size_t len, char* buffer) {
	node *f = vfs_read_fd(file);
	if (f == 0) return E_INVALID_FD;
	return f->read(offset, len, buffer);
}

int write(FILE file, size_t offset, size_t len, char* buffer) {
	node *f = vfs_read_fd(file);
	if (f == 0) return E_INVALID_FD;
	return f->write(offset, len, buffer);
}

int link(char* from, char* to, int mode) {
	node *f1 = vfs_find(root, from);
	if (f1 == 0) return E_NOT_FOUND;
	node *f2 = (to == 0 ? 0 : vfs_find(root, to));
	return f1->link(f2, mode);
}