diff options
author | Ian Moffett <ian@osmora.org> | 2024-08-21 11:58:32 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2024-08-21 12:03:58 -0400 |
commit | 8bc9542f9dadb9a99f92c20af3291a048e3a75fd (patch) | |
tree | ab00e30f437ec5f6b99fab6866926c2d209d6e2e /sys/kern/vfs_syscalls.c | |
parent | 8f2a455cf3866857349e377cd2cf2bb898e0a494 (diff) |
kernel: vfs: Add sys_close()
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'sys/kern/vfs_syscalls.c')
-rw-r--r-- | sys/kern/vfs_syscalls.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 937ae87..77070ab 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -34,6 +34,7 @@ #include <sys/errno.h> #include <sys/sio.h> #include <sys/filedesc.h> +#include <sys/atomic.h> #include <sys/namei.h> #include <sys/proc.h> #include <sys/limits.h> @@ -141,6 +142,40 @@ sys_open(struct syscall_args *scargs) /* * arg0: fd + */ +scret_t +sys_close(struct syscall_args *args) +{ + struct filedesc *filedes; + struct proc *td; + int fd = args->arg0; + + if ((filedes = fd_get(fd)) == NULL) { + return -EBADF; + } + + /* Return if other threads still hold a ref */ + if (atomic_dec_int(&filedes->refcnt) > 0) { + return 0; + } + + td = this_td(); + + /* + * Each file descriptor structure references a vnode, + * we want to reclaim it or at the very least drop + * one of its references. After we've cleaned up within + * the file descriptor, we can clear it from the fd table + * and free up the memory for it. + */ + vfs_release_vnode(filedes->vp); + td->fds[fd] = NULL; + dynfree(filedes); + return 0; +} + +/* + * arg0: fd * arg1: buf * arg2: count */ |