summaryrefslogtreecommitdiff
path: root/src/kernel/syscalls.c
diff options
context:
space:
mode:
authordzwdz2021-09-08 20:22:45 +0200
committerdzwdz2021-09-08 20:22:45 +0200
commit416063625be0f70bdf84506f04ba30adaa3ba0b0 (patch)
tree1398d23d8f9b216c84e75e639d06760747de456d /src/kernel/syscalls.c
parentf44b80c3f0004418c4953f0a2f32f7bec2e26e36 (diff)
copy _syscall_fs_open's argument to a new buffer instead of a shared one
this will be needed for storing vfs_op's properly
Diffstat (limited to 'src/kernel/syscalls.c')
-rw-r--r--src/kernel/syscalls.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c
index 124333a..48cb709 100644
--- a/src/kernel/syscalls.c
+++ b/src/kernel/syscalls.c
@@ -69,7 +69,7 @@ int _syscall_fork(void) {
handle_t _syscall_open(const user_ptr path, int len) {
struct vfs_mount *mount;
- static char path_buf[PATH_MAX];
+ char *path_buf = NULL;
if (len > PATH_MAX)
return -1;
@@ -81,15 +81,17 @@ handle_t _syscall_open(const user_ptr path, int len) {
// copy the path to the kernel
// note: the cast is necessary because the function usually accepts user_ptrs
// it can handle copies to physical memory too, though
+ // note 2: path_buf gets freed in vfs_backend_finish
+ path_buf = kmalloc(len);
if (!virt_cpy(NULL, (uintptr_t)path_buf,
process_current->pages, path, len))
- return -1;
+ goto fail;
len = path_simplify(path_buf, path_buf, len);
- if (len < 0) return -1;
+ if (len < 0) goto fail;
mount = vfs_mount_resolve(process_current->mount, path_buf, len);
- if (!mount) return -1;
+ if (!mount) goto fail;
vfs_backend_dispatch(mount->backend, (struct vfs_op) {
.type = VFSOP_OPEN,
@@ -98,7 +100,11 @@ handle_t _syscall_open(const user_ptr path, int len) {
.path_len = len - mount->prefix_len,
}
});
- // doesn't return
+ // doesn't return / fallthrough to fail
+
+fail:
+ kfree(path_buf);
+ return -1;
}
int _syscall_mount(handle_t handle, const user_ptr path, int len) {