summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/init/main.c7
-rw-r--r--src/init/syscalls.c4
-rw-r--r--src/kernel/handle.h6
-rw-r--r--src/kernel/syscalls.c34
-rw-r--r--src/kernel/vfs/backend.h1
-rw-r--r--src/shared/syscalls.h7
6 files changed, 59 insertions, 0 deletions
diff --git a/src/init/main.c b/src/init/main.c
index 939f15f..deacb15 100644
--- a/src/init/main.c
+++ b/src/init/main.c
@@ -9,6 +9,7 @@ __attribute__((section("text")))
int tty_fd;
void misc_tests(void);
+void fs_test(void);
// takes a cstring and copies it right before a page boundary
const char *multipageify(const char *str);
@@ -21,10 +22,16 @@ int main(void) {
log(" opened /tty ");
misc_tests();
+ fs_test();
_syscall_exit(argify("my job here is done."));
}
+void fs_test(void) {
+ handle_t front, back;
+ front = _syscall_fs_create((void*)&back); // TODO change user_ptr to void*
+}
+
void misc_tests(void) {
int res;
res = _syscall_open(argify("/tty/nonexistant"));
diff --git a/src/init/syscalls.c b/src/init/syscalls.c
index 730a243..4c645c2 100644
--- a/src/init/syscalls.c
+++ b/src/init/syscalls.c
@@ -36,3 +36,7 @@ int _syscall_write(handle_t handle, user_ptr buf, int len) {
int _syscall_close(handle_t handle) {
return _syscall(_SYSCALL_CLOSE, handle, 0, 0);
}
+
+handle_t _syscall_fs_create(user_ptr back) {
+ return _syscall(_SYSCALL_FS_CREATE, (int)back, 0, 0);
+}
diff --git a/src/kernel/handle.h b/src/kernel/handle.h
index 0bf0f33..4ec8e57 100644
--- a/src/kernel/handle.h
+++ b/src/kernel/handle.h
@@ -10,6 +10,9 @@ typedef int handle_t; // TODO duplicated in syscalls.h
enum handle_type {
HANDLE_EMPTY,
HANDLE_FILE,
+
+ HANDLE_FS_FRONT,
+ HANDLE_FS_BACK,
};
struct handle {
@@ -19,5 +22,8 @@ struct handle {
struct vfs_backend *backend;
int id;
} file;
+ struct {
+ struct vfs_backend *backend;
+ } fs;
};
};
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c
index 6b0f4a2..5d792ce 100644
--- a/src/kernel/syscalls.c
+++ b/src/kernel/syscalls.c
@@ -161,6 +161,38 @@ int _syscall_close(handle_t handle) {
return -1;
}
+handle_t _syscall_fs_create(user_ptr back_user) {
+ handle_t front, back = 0;
+ struct vfs_backend *backend;
+
+ front = process_find_handle(process_current);
+ if (front < 0) goto fail;
+ // the type needs to be set here so process_find_handle skips this handle
+ process_current->handles[front].type = HANDLE_FS_FRONT;
+
+ back = process_find_handle(process_current);
+ if (back < 0) goto fail;
+ process_current->handles[back].type = HANDLE_FS_BACK;
+
+ // copy the back handle to back_user
+ if (!virt_cpy(process_current->pages, back_user,
+ NULL, (uintptr_t)&back, sizeof(handle_t)))
+ goto fail;
+
+ backend = kmalloc(sizeof(struct vfs_backend));
+ backend->type = VFS_BACK_USER;
+ process_current->handles[front].fs.backend = backend;
+ process_current->handles[back ].fs.backend = backend;
+
+ return front;
+fail:
+ if (front >= 0)
+ process_current->handles[front].type = HANDLE_EMPTY;
+ if (back >= 0)
+ process_current->handles[back].type = HANDLE_EMPTY;
+ return -1;
+}
+
int syscall_handler(int num, int a, int b, int c) {
switch (num) {
case _SYSCALL_EXIT:
@@ -179,6 +211,8 @@ int syscall_handler(int num, int a, int b, int c) {
return _syscall_write(a, b, c);
case _SYSCALL_CLOSE:
return _syscall_close(a);
+ case _SYSCALL_FS_CREATE:
+ return _syscall_fs_create(a);
default:
tty_const("unknown syscall ");
panic();
diff --git a/src/kernel/vfs/backend.h b/src/kernel/vfs/backend.h
index 6a8bee6..fe46db1 100644
--- a/src/kernel/vfs/backend.h
+++ b/src/kernel/vfs/backend.h
@@ -3,6 +3,7 @@
enum vfs_backend_type {
VFS_BACK_ROOT,
+ VFS_BACK_USER,
};
// describes something which can acts as an access function
diff --git a/src/shared/syscalls.h b/src/shared/syscalls.h
index 0222f37..29836b0 100644
--- a/src/shared/syscalls.h
+++ b/src/shared/syscalls.h
@@ -19,6 +19,8 @@ enum {
_SYSCALL_READ,
_SYSCALL_WRITE,
_SYSCALL_CLOSE,
+
+ _SYSCALL_FS_CREATE,
};
/** Kills the current process.
@@ -43,3 +45,8 @@ int _syscall_mount(handle_t, const user_ptr path, int len);
int _syscall_read(handle_t, user_ptr buf, int len);
int _syscall_write(handle_t, user_ptr buf, int len);
int _syscall_close(handle_t);
+
+/** Creates a pair of front/back filesystem handles.
+ * @param back a pointer to a handle_t which will store the back pointer
+ */
+handle_t _syscall_fs_create(user_ptr back);