From d461ad1a0be10f5f98adfe2b0a6a5ff008e0bb83 Mon Sep 17 00:00:00 2001 From: Matheus Date: Wed, 12 Jun 2024 18:54:55 -0300 Subject: [PATCH] file: fd_(set/get)flags() --- kernel-src/fs/file.c | 28 ++++++++++++++++++++++++++++ kernel-src/include/kernel/file.h | 2 ++ kernel-src/sys/syscalls/fcntl.c | 9 ++++++++- 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/kernel-src/fs/file.c b/kernel-src/fs/file.c index f6f3493f..8ab0e4f1 100644 --- a/kernel-src/fs/file.c +++ b/kernel-src/fs/file.c @@ -84,6 +84,34 @@ file_t *fd_get(int fd) { return file; } +int fd_setflags(int fd, int flags) { + int error = 0; + proc_t *proc = _cpu()->thread->proc; + MUTEX_ACQUIRE(&proc->fdmutex, false); + + if (proc->fd[fd].file) + proc->fd[fd].flags = flags; + else + error = EBADF; + + MUTEX_RELEASE(&proc->fdmutex); + return error; +} + +int fd_getflags(int fd, int *flags) { + int error = 0; + proc_t *proc = _cpu()->thread->proc; + MUTEX_ACQUIRE(&proc->fdmutex, false); + + if (proc->fd[fd].file) + *flags = proc->fd[fd].flags; + else + error = EBADF; + + MUTEX_RELEASE(&proc->fdmutex); + return error; +} + void fd_release(file_t *file) { FILE_RELEASE(file); } diff --git a/kernel-src/include/kernel/file.h b/kernel-src/include/kernel/file.h index 6da8ebef..96d8aa6d 100644 --- a/kernel-src/include/kernel/file.h +++ b/kernel-src/include/kernel/file.h @@ -26,6 +26,8 @@ int fd_new(int flags, file_t **file, int *fd); int fd_close(int fd); int fd_dup(int oldfd, int newfd, bool exact, int flags, int *ret); int fd_clone(proc_t *proc); +int fd_setflags(int fd, int flags); +int fd_getflags(int fd, int *flags); #define FILE_LOCK(x) MUTEX_ACQUIRE(&(x)->mutex, false) #define FILE_UNLOCK(x) MUTEX_RELEASE(&(x)->mutex) diff --git a/kernel-src/sys/syscalls/fcntl.c b/kernel-src/sys/syscalls/fcntl.c index ecf70398..d3d01e99 100644 --- a/kernel-src/sys/syscalls/fcntl.c +++ b/kernel-src/sys/syscalls/fcntl.c @@ -42,9 +42,14 @@ syscallret_t syscall_fcntl(context_t *, int fd, int cmd, uint64_t arg) { FILE_UNLOCK(file); break; case F_SETFD: - case F_GETFD: // TODO implement this + ret.errno = fd_setflags(fd, arg); ret.ret = 0; break; + case F_GETFD: + int flg; + ret.errno = fd_getflags(fd, &flg); + ret.ret = flg; + break; default: ret.errno = EINVAL; goto cleanup; @@ -52,6 +57,8 @@ syscallret_t syscall_fcntl(context_t *, int fd, int cmd, uint64_t arg) { ret.errno = 0; cleanup: + ret.ret = ret.errno ? -1 : ret.ret; + fd_release(file); return ret; }