diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/kernel/fd.c | 8 | ||||
-rw-r--r-- | src/kernel/fd.h | 4 | ||||
-rw-r--r-- | src/kernel/syscalls.c | 11 | ||||
-rw-r--r-- | src/kernel/vfs/mount.h | 2 |
4 files changed, 24 insertions, 1 deletions
diff --git a/src/kernel/fd.c b/src/kernel/fd.c index 77fea05..810cdb7 100644 --- a/src/kernel/fd.c +++ b/src/kernel/fd.c @@ -7,8 +7,11 @@ static int fdop_special_tty(struct fdop_args *args); int fdop_dispatch(struct fdop_args args) { switch(args.fd->type) { - case FD_EMPTY: + case FD_EMPTY: { + if (args.type == FDOP_MOUNT) // mounting an empty fd is allowed + return 0; return -1; + } case FD_SPECIAL_TTY: return fdop_special_tty(&args); default: @@ -18,6 +21,9 @@ int fdop_dispatch(struct fdop_args args) { static int fdop_special_tty(struct fdop_args *args) { switch(args->type) { + case FDOP_MOUNT: + return 0; // no special action needed + case FDOP_READ: return -1; // input not implemented yet diff --git a/src/kernel/fd.h b/src/kernel/fd.h index b35c979..bcc9902 100644 --- a/src/kernel/fd.h +++ b/src/kernel/fd.h @@ -17,6 +17,7 @@ struct fd { enum fdop { // describes the operations which can be done on file descriptors + FDOP_MOUNT, // also closes the original fd FDOP_READ, FDOP_WRITE, FDOP_CLOSE, @@ -26,6 +27,9 @@ struct fdop_args { enum fdop type; struct fd *fd; union { + struct { // FDOP_MOUNT + struct mount *target; + } mnt; struct { // FDOP_READ, FDOP_WRITE user_ptr ptr; size_t len; diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c index bf17fd3..737484d 100644 --- a/src/kernel/syscalls.c +++ b/src/kernel/syscalls.c @@ -104,8 +104,10 @@ int _syscall_fd_mount(fd_t fd, const user_ptr path, int len) { struct virt_iter iter; struct vfs_mount *mount; char *path_buf; + int res; if (len > PATH_MAX) return -1; + if (fd < 0 || fd >= FD_MAX) return -1; // copy the path to the kernel path_buf = kmalloc(len); @@ -124,10 +126,19 @@ int _syscall_fd_mount(fd_t fd, const user_ptr path, int len) { mount->prev = process_current->mount; mount->prefix = path_buf; mount->prefix_len = len; + memcpy(&mount->fd, &process_current->fds[fd], sizeof(struct fd)); + + res = fdop_dispatch((struct fdop_args){ + .type = FDOP_MOUNT, + .fd = &process_current->fds[fd], + .mnt = {mount}, + }); + if (res < 0) goto fail; process_current->mount = mount; return 0; fail: kfree(path_buf); + kfree(mount); return -1; } diff --git a/src/kernel/vfs/mount.h b/src/kernel/vfs/mount.h index b99f97e..3e9d8ae 100644 --- a/src/kernel/vfs/mount.h +++ b/src/kernel/vfs/mount.h @@ -1,7 +1,9 @@ #pragma once +#include <kernel/fd.h> struct vfs_mount { struct vfs_mount *prev; char *prefix; size_t prefix_len; + struct fd fd; }; |