diff options
author | dzwdz | 2021-11-02 20:22:51 +0100 |
---|---|---|
committer | dzwdz | 2021-11-02 20:22:51 +0100 |
commit | 55121883effaca2c8b35cff956092e6f0a99f8ce (patch) | |
tree | cb38e53d855e3dab3eb6962fb19d9bff7c7bc20e /src/kernel | |
parent | a957c8f0c6b35171378522e03b4360cfc5527832 (diff) |
fork2() refactor: implement fs_fork2()
Diffstat (limited to 'src/kernel')
-rw-r--r-- | src/kernel/syscalls.c | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c index d5c2c8f..5cee090 100644 --- a/src/kernel/syscalls.c +++ b/src/kernel/syscalls.c @@ -165,29 +165,34 @@ int _syscall_close(handle_t handle) { return -1; } -handle_t _syscall_fs_create(void) { - handle_t front = 0; +handle_t _syscall_fs_fork2(void) { struct vfs_backend *backend; + struct process *child; + handle_t front; 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 + if (front < 0) return -1; process_current->handles[front].type = HANDLE_FS_FRONT; + /* so this can't return 0 in the parent or it will make it think that it's + * the child. i could make fork()s return -1 in the child but that's weird. + * + * also there's this whole thing with handling errors here properly and + * errno + * TODO figure this out */ + if (front == 0) panic_unimplemented(); + backend = kmalloc(sizeof *backend); // TODO never freed backend->type = VFS_BACK_USER; backend->handler = NULL; backend->queue = NULL; - process_current->handles[front].fs.backend = backend; - - process_current->controlled = backend; + child = process_fork(process_current); + child->controlled = backend; + regs_savereturn(&child->regs, 0); + process_current->handles[front].fs.backend = backend; return front; -fail: - if (front >= 0) - process_current->handles[front].type = HANDLE_EMPTY; - return -1; } int _syscall_fs_wait(char __user *buf, int max_len, struct fs_wait_response __user *res) { @@ -269,8 +274,8 @@ int _syscall(int num, int a, int b, int c, int d) { return _syscall_write(a, (userptr_t)b, c, d); case _SYSCALL_CLOSE: return _syscall_close(a); - case _SYSCALL_FS_CREATE: - return _syscall_fs_create(); + case _SYSCALL_FS_FORK2: + return _syscall_fs_fork2(); case _SYSCALL_FS_WAIT: return _syscall_fs_wait((userptr_t)a, b, (userptr_t)c); case _SYSCALL_FS_RESPOND: |