From 8bc9542f9dadb9a99f92c20af3291a048e3a75fd Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Wed, 21 Aug 2024 11:58:32 -0400 Subject: kernel: vfs: Add sys_close() Signed-off-by: Ian Moffett --- sys/kern/vfs_syscalls.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'sys/kern/vfs_syscalls.c') 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 #include #include +#include #include #include #include @@ -139,6 +140,40 @@ sys_open(struct syscall_args *scargs) return filedes->fdno; } +/* + * 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 -- cgit v1.2.3