summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/init/main.c10
-rw-r--r--src/init/syscalls.c4
-rw-r--r--src/kernel/proc.c1
-rw-r--r--src/kernel/proc.h3
-rw-r--r--src/kernel/syscalls.c55
-rw-r--r--src/kernel/syscalls.h3
-rw-r--r--src/kernel/vfs/mount.h7
7 files changed, 79 insertions, 4 deletions
diff --git a/src/init/main.c b/src/init/main.c
index 51764ce..0c5f034 100644
--- a/src/init/main.c
+++ b/src/init/main.c
@@ -13,10 +13,16 @@ const char *multipageify(const char *str) {
return out;
}
+#define mount(path) _syscall_mount(path, sizeof(path)-1, 0)
+
int main() {
+ mount("/");
+ mount("/some/where");
+ mount("/some");
+
_syscall_fs_open(
- multipageify("/some/../path"),
- sizeof("/some/../path") - 1);
+ multipageify("/some/where/file"),
+ sizeof("/some/where/file") - 1);
_syscall_exit("bye from init! ",
sizeof("bye from init! ") - 1);
diff --git a/src/init/syscalls.c b/src/init/syscalls.c
index b0e1587..fb59bd3 100644
--- a/src/init/syscalls.c
+++ b/src/init/syscalls.c
@@ -20,6 +20,10 @@ fd_t _syscall_fs_open(const char *path, size_t len) {
return _syscall(_SYSCALL_FS_OPEN, (int)path, len, 0);
}
+int _syscall_mount(const char *path, int len, fd_t fd) {
+ return _syscall(_SYSCALL_MOUNT, (int)path, len, fd);
+}
+
int _syscall_debuglog(const char *msg, size_t len) {
return _syscall(_SYSCALL_DEBUGLOG, (int)msg, len, 0);
}
diff --git a/src/kernel/proc.c b/src/kernel/proc.c
index e1b650c..f826d8a 100644
--- a/src/kernel/proc.c
+++ b/src/kernel/proc.c
@@ -16,6 +16,7 @@ struct process *process_seed() {
proc->sibling = NULL;
proc->child = NULL;
proc->parent = NULL;
+ proc->mount = NULL;
proc->id = next_pid++;
process_first = proc;
diff --git a/src/kernel/proc.h b/src/kernel/proc.h
index c2dfde4..ffc342a 100644
--- a/src/kernel/proc.h
+++ b/src/kernel/proc.h
@@ -1,5 +1,6 @@
#pragma once
#include <kernel/arch/generic.h>
+#include <kernel/vfs/mount.h>
enum process_state {
PS_RUNNING,
@@ -25,6 +26,8 @@ struct process {
// PS_WAITS4CHILDDEATH - buffer for said message
void *saved_addr;
size_t saved_len;
+
+ struct vfs_mount *mount;
};
extern struct process *process_first;
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c
index 13e0535..0a88c98 100644
--- a/src/kernel/syscalls.c
+++ b/src/kernel/syscalls.c
@@ -67,12 +67,13 @@ int _syscall_fork() {
fd_t _syscall_fs_open(const char *path, size_t len) {
struct virt_iter iter;
- static char buffer[PATH_MAX]; // holds the simplified path
+ struct vfs_mount *mount = process_current->mount;
+ static char buffer[PATH_MAX]; // holds the path
size_t pos = 0;
if (len > PATH_MAX) return -1;
- // copy the path to buffer
+ // copy the path to the kernel
virt_iter_new(&iter, (void*)path, len, process_current->pages, true, false);
while (virt_iter_next(&iter)) {
memcpy(buffer + pos, iter.frag, iter.frag_len);
@@ -83,7 +84,55 @@ fd_t _syscall_fs_open(const char *path, size_t len) {
len = path_simplify(buffer, buffer, len);
if (len < 0) return -1;
+ // find mount
+ for (mount = process_current->mount; mount; mount = mount->prev) {
+ if (mount->prefix_len > len)
+ continue;
+ if (memcmp(mount->prefix, buffer, mount->prefix_len) == 0)
+ break;
+ }
+
tty_write(buffer, len);
+ tty_const(" from mount ");
+ if (mount)
+ tty_write(mount->prefix, mount->prefix_len);
+ else
+ tty_const("[none]");
+
+ return -1;
+}
+
+int _syscall_mount(const char *path, int len, fd_t fd) {
+ struct virt_iter iter;
+ struct vfs_mount *mount;
+ char *path_buf;
+ size_t pos = 0;
+
+ if (len > PATH_MAX) return -1;
+
+ // copy the path to the kernel
+ virt_iter_new(&iter, (void*)path, len, process_current->pages, true, false);
+ path_buf = kmalloc(len);
+ while (virt_iter_next(&iter)) { // TODO abstract away
+ memcpy(path_buf + pos, iter.frag, iter.frag_len);
+ pos += iter.frag_len;
+ }
+ if (iter.error) goto fail;
+
+ // simplify it
+ len = path_simplify(path_buf, path_buf, len);
+ if (len < 0) goto fail;
+ // TODO remove trailing slash
+
+ // append to mount list
+ mount = kmalloc(sizeof(struct vfs_mount));
+ mount->prev = process_current->mount;
+ mount->prefix = path_buf;
+ mount->prefix_len = len;
+ process_current->mount = mount;
+ return 0;
+fail:
+ kfree(path_buf);
return -1;
}
@@ -109,6 +158,8 @@ int syscall_handler(int num, int a, int b, int c) {
return _syscall_fork();
case _SYSCALL_FS_OPEN:
return _syscall_fs_open((void*)a, b);
+ case _SYSCALL_MOUNT:
+ return _syscall_mount((void*)a, b, c);
case _SYSCALL_DEBUGLOG:
return _syscall_debuglog((void*)a, b);
default:
diff --git a/src/kernel/syscalls.h b/src/kernel/syscalls.h
index 5f55454..c8dca05 100644
--- a/src/kernel/syscalls.h
+++ b/src/kernel/syscalls.h
@@ -3,6 +3,7 @@
#include <stddef.h>
typedef int fd_t;
+typedef int fs_handle_t;
enum {
// idc about stable syscall numbers just yet
@@ -11,6 +12,7 @@ enum {
_SYSCALL_FORK,
_SYSCALL_FS_OPEN,
+ _SYSCALL_MOUNT,
_SYSCALL_DEBUGLOG
};
@@ -32,6 +34,7 @@ int _syscall_await(char *buf, int len);
int _syscall_fork();
fd_t _syscall_fs_open(const char *path, size_t len);
+int _syscall_mount(const char *path, int len, fd_t fd);
/** Prints a message to the debug console.
* @return the amount of bytes written (can be less than len)
diff --git a/src/kernel/vfs/mount.h b/src/kernel/vfs/mount.h
new file mode 100644
index 0000000..b99f97e
--- /dev/null
+++ b/src/kernel/vfs/mount.h
@@ -0,0 +1,7 @@
+#pragma once
+
+struct vfs_mount {
+ struct vfs_mount *prev;
+ char *prefix;
+ size_t prefix_len;
+};