summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorAnton Kling <anton@kling.gg>2024-11-22 22:33:06 +0100
committerAnton Kling <anton@kling.gg>2024-11-22 22:33:06 +0100
commit8fa2af9678b9e257a1dfb1e5111f35d22366f2c6 (patch)
treed82d3b9678b2fcfdc901455f4ca2ed13dc49aaa7 /kernel
parent8827f3033d76b0d9c7d8d8225077176a813f7f49 (diff)
vfs: Add dup()
Diffstat (limited to 'kernel')
-rw-r--r--kernel/cpu/syscall.c5
-rw-r--r--kernel/fs/vfs.c13
-rw-r--r--kernel/fs/vfs.h1
3 files changed, 19 insertions, 0 deletions
diff --git a/kernel/cpu/syscall.c b/kernel/cpu/syscall.c
index aad0284..d4db1dd 100644
--- a/kernel/cpu/syscall.c
+++ b/kernel/cpu/syscall.c
@@ -439,6 +439,10 @@ int syscall_read(int fd, void *buf, size_t count) {
return rc;
}
+int syscall_dup(int fd) {
+ return vfs_dup(fd);
+}
+
int syscall_dup2(SYS_DUP2_PARAMS *args) {
return vfs_dup2(args->org_fd, args->new_fd);
}
@@ -700,6 +704,7 @@ int (*syscall_functions[])() = {
(void(*))syscall_queue_wait,
(void(*))syscall_sendfile,
(void(*))syscall_shm_unlink,
+ (void(*))syscall_dup,
};
void int_syscall(reg_t *r);
diff --git a/kernel/fs/vfs.c b/kernel/fs/vfs.c
index 9684a18..1f28f13 100644
--- a/kernel/fs/vfs.c
+++ b/kernel/fs/vfs.c
@@ -395,6 +395,19 @@ vfs_vm_object_t *vfs_get_vm_object(int fd, u64 length, u64 offset) {
return r;
}
+int vfs_dup(int fd) {
+ vfs_fd_t *ptr = get_vfs_fd(fd, NULL);
+ if (!ptr) {
+ return -EBADF;
+ }
+ int index;
+ if (!relist_add(&current_task->file_descriptors, ptr, &index)) {
+ return -EMFILE;
+ }
+ ptr->reference_count++;
+ return index;
+}
+
int vfs_dup2(int org_fd, int new_fd) {
if (org_fd == new_fd) {
return -EINVAL;
diff --git a/kernel/fs/vfs.h b/kernel/fs/vfs.h
index 396802b..e22897e 100644
--- a/kernel/fs/vfs.h
+++ b/kernel/fs/vfs.h
@@ -77,6 +77,7 @@ int raw_vfs_pwrite(vfs_fd_t *vfs_fd, void *buf, u64 count, u64 offset);
int raw_vfs_pread(vfs_fd_t *vfs_fd, void *buf, u64 count, u64 offset);
int vfs_pread(int fd, void *buf, u64 count, u64 offset);
vfs_vm_object_t *vfs_get_vm_object(int fd, u64 length, u64 offset);
+int vfs_dup(int fd);
int vfs_dup2(int org_fd, int new_fd);
vfs_inode_t *vfs_internal_open(const char *file);
int vfs_mkdir(const char *path, int mode);