diff options
-rw-r--r-- | src/init/main.c | 7 | ||||
-rw-r--r-- | src/init/syscalls.c | 4 | ||||
-rw-r--r-- | src/kernel/handle.h | 6 | ||||
-rw-r--r-- | src/kernel/syscalls.c | 34 | ||||
-rw-r--r-- | src/kernel/vfs/backend.h | 1 | ||||
-rw-r--r-- | src/shared/syscalls.h | 7 |
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); |