summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Kling <anton@kling.gg>2024-06-26 20:37:16 +0200
committerAnton Kling <anton@kling.gg>2024-06-26 20:37:16 +0200
commita7eeb66a1b3ab5f4aea31798a384d7c5b886b3e1 (patch)
tree799f1134ab2ab22eaebb832aa6be1181901b3fc3
parent8c032568c572ad346491f78325c278b886122ec5 (diff)
Libc/Kernel: Add fcntl()
-rw-r--r--include/fcntl.h (renamed from userland/libc/include/fcntl.h)7
-rw-r--r--kernel/cpu/syscall.c19
-rw-r--r--kernel/fs/vfs.c1
-rw-r--r--kernel/fs/vfs.h9
4 files changed, 25 insertions, 11 deletions
diff --git a/userland/libc/include/fcntl.h b/include/fcntl.h
index 57c968a..af2a68f 100644
--- a/userland/libc/include/fcntl.h
+++ b/include/fcntl.h
@@ -1,4 +1,3 @@
-// FIXME: Is there some standard value for this?
#define O_NONBLOCK (1 << 0)
#define O_READ (1 << 1)
#define O_WRITE (1 << 2)
@@ -10,5 +9,11 @@
#define O_WRONLY O_WRITE
#define O_RDWR (O_WRITE | O_READ)
+#define F_GETFL 0
+#define F_SETFL 1
+
+#ifndef KERNEL
int open(const char *file, int flags, ...);
int open_process(int pid);
+int fcntl(int fd, int cmd, ...);
+#endif
diff --git a/kernel/cpu/syscall.c b/kernel/cpu/syscall.c
index adbb27a..4a446d5 100644
--- a/kernel/cpu/syscall.c
+++ b/kernel/cpu/syscall.c
@@ -4,6 +4,7 @@
#include <cpu/syscall.h>
#include <drivers/pst.h>
#include <errno.h>
+#include <fcntl.h>
#include <fs/tmpfs.h>
#include <fs/vfs.h>
#include <interrupts.h>
@@ -169,6 +170,22 @@ int syscall_getpeername(int sockfd, struct sockaddr *restrict addr,
return 0;
}
+int syscall_fcntl(int fd, int cmd, int arg) {
+ vfs_fd_t *fd_ptr = get_vfs_fd(fd, NULL);
+ if (!fd_ptr) {
+ return -EBADF;
+ }
+ if (F_GETFL == cmd) {
+ return fd_ptr->flags;
+ } else if (F_SETFL == cmd) {
+ fd_ptr->flags = arg;
+ return 0;
+ } else {
+ return -EINVAL;
+ }
+ return 0;
+}
+
int (*syscall_functions[])() = {
(void(*))syscall_open, (void(*))syscall_read,
(void(*))syscall_write, (void(*))syscall_pread,
@@ -190,7 +207,7 @@ int (*syscall_functions[])() = {
(void(*))syscall_randomfill, (void(*))syscall_munmap,
(void(*))syscall_open_process, (void(*))syscall_lseek,
(void(*))syscall_connect, (void(*))syscall_setsockopt,
- (void(*))syscall_getpeername,
+ (void(*))syscall_getpeername, (void(*))syscall_fcntl,
};
void int_syscall(reg_t *r);
diff --git a/kernel/fs/vfs.c b/kernel/fs/vfs.c
index 21c98cf..dfdaf44 100644
--- a/kernel/fs/vfs.c
+++ b/kernel/fs/vfs.c
@@ -3,6 +3,7 @@
#include <fs/vfs.h>
#include <mmu.h>
#include <poll.h>
+#include <fcntl.h>
vfs_inode_t *root_dir;
vfs_mounts_t mounts[10];
diff --git a/kernel/fs/vfs.h b/kernel/fs/vfs.h
index 64a7a80..080a663 100644
--- a/kernel/fs/vfs.h
+++ b/kernel/fs/vfs.h
@@ -13,15 +13,6 @@ typedef struct vfs_mounts vfs_mounts_t;
#include <sys/stat.h>
#include <typedefs.h>
-// FIXME: Is there some standard value for this?
-#define O_NONBLOCK (1 << 0)
-#define O_READ (1 << 1)
-#define O_WRITE (1 << 2)
-#define O_CREAT (1 << 3)
-#define O_RDONLY O_READ
-#define O_WRONLY O_WRITE
-#define O_RDWR (O_WRITE | O_READ)
-
#define FS_TYPE_FILE 0
#define FS_TYPE_UNIX_SOCKET 1
#define FS_TYPE_CHAR_DEVICE 2