summaryrefslogtreecommitdiff
path: root/src/kernel/vfs/node.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/vfs/node.cpp')
-rw-r--r--src/kernel/vfs/node.cpp122
1 files changed, 122 insertions, 0 deletions
diff --git a/src/kernel/vfs/node.cpp b/src/kernel/vfs/node.cpp
new file mode 100644
index 0000000..9900a3c
--- /dev/null
+++ b/src/kernel/vfs/node.cpp
@@ -0,0 +1,122 @@
+#include "node.h"
+#include "vdir.h"
+#include <core/monitor.h>
+
+int node::open(process *proc, int mode) {
+ //TODO : permission checks
+ 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;
+
+void vfs_setup() {
+ root = new vdir(0);
+ root->add_child(".dev", new vdir(root));
+
+ monitor_write("[VFS] ");
+}
+
+node* vfs_find(node* root, char* path) {
+ node* el = root;
+ char *member = path;
+
+ while (*path != 0 && el != 0) {
+ if (*path == '/') {
+ if (member == path) {
+ member++;
+ path++;
+ } else {
+ *path = 0;
+ el = el->get_child(member);
+ 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
+ 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) {
+ return E_NOT_IMPLEMENTED;
+}