From 8e4216215e4f0ded6f74ff9ed95f600b5a71a35f Mon Sep 17 00:00:00 2001 From: Bananymous Date: Thu, 17 Aug 2023 12:03:29 +0300 Subject: [PATCH] Kernel/LibC: add dup() syscall and function --- kernel/include/kernel/OpenFileDescriptorSet.h | 1 + kernel/include/kernel/Process.h | 1 + kernel/kernel/OpenFileDescriptorSet.cpp | 13 +++++++++++++ kernel/kernel/Process.cpp | 6 ++++++ kernel/kernel/Syscall.cpp | 3 +++ libc/include/sys/syscall.h | 15 ++++++++------- libc/unistd.cpp | 5 +++++ 7 files changed, 37 insertions(+), 7 deletions(-) diff --git a/kernel/include/kernel/OpenFileDescriptorSet.h b/kernel/include/kernel/OpenFileDescriptorSet.h index 4a18a7b6..ec5a5bcb 100644 --- a/kernel/include/kernel/OpenFileDescriptorSet.h +++ b/kernel/include/kernel/OpenFileDescriptorSet.h @@ -25,6 +25,7 @@ namespace Kernel BAN::ErrorOr pipe(int fds[2]); + BAN::ErrorOr dup(int); BAN::ErrorOr dup2(int, int); BAN::ErrorOr seek(int fd, off_t offset, int whence); diff --git a/kernel/include/kernel/Process.h b/kernel/include/kernel/Process.h index 36d7c9bd..934a7217 100644 --- a/kernel/include/kernel/Process.h +++ b/kernel/include/kernel/Process.h @@ -86,6 +86,7 @@ namespace Kernel BAN::ErrorOr sys_creat(BAN::StringView name, mode_t); BAN::ErrorOr sys_pipe(int fildes[2]); + BAN::ErrorOr sys_dup(int fildes); BAN::ErrorOr sys_dup2(int fildes, int fildes2); BAN::ErrorOr sys_seek(int fd, off_t offset, int whence); diff --git a/kernel/kernel/OpenFileDescriptorSet.cpp b/kernel/kernel/OpenFileDescriptorSet.cpp index 38e09837..9d4829e9 100644 --- a/kernel/kernel/OpenFileDescriptorSet.cpp +++ b/kernel/kernel/OpenFileDescriptorSet.cpp @@ -85,6 +85,19 @@ namespace Kernel return {}; } + BAN::ErrorOr OpenFileDescriptorSet::dup(int fildes) + { + TRY(validate_fd(fildes)); + + int result = TRY(get_free_fd()); + m_open_files[result] = m_open_files[fildes]; + + if (m_open_files[result]->flags & O_WRONLY && m_open_files[result]->inode->is_pipe()) + ((Pipe*)m_open_files[result]->inode.ptr())->clone_writing(); + + return result; + } + BAN::ErrorOr OpenFileDescriptorSet::dup2(int fildes, int fildes2) { if (fildes2 < 0 || fildes2 >= (int)m_open_files.size()) diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index f0426f97..b2ab8696 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -596,6 +596,12 @@ namespace Kernel return 0; } + BAN::ErrorOr Process::sys_dup(int fildes) + { + LockGuard _(m_lock); + return TRY(m_open_file_descriptors.dup(fildes)); + } + BAN::ErrorOr Process::sys_dup2(int fildes, int fildes2) { LockGuard _(m_lock); diff --git a/kernel/kernel/Syscall.cpp b/kernel/kernel/Syscall.cpp index de6137aa..5cde2d39 100644 --- a/kernel/kernel/Syscall.cpp +++ b/kernel/kernel/Syscall.cpp @@ -149,6 +149,9 @@ namespace Kernel case SYS_PIPE: ret = Process::current().sys_pipe((int*)arg1); break; + case SYS_DUP: + ret = Process::current().sys_dup((int)arg1); + break; case SYS_DUP2: ret = Process::current().sys_dup2((int)arg1, (int)arg2); break; diff --git a/libc/include/sys/syscall.h b/libc/include/sys/syscall.h index d5ef8769..912ace01 100644 --- a/libc/include/sys/syscall.h +++ b/libc/include/sys/syscall.h @@ -40,13 +40,14 @@ __BEGIN_DECLS #define SYS_SET_PWD 33 #define SYS_CLOCK_GETTIME 34 #define SYS_PIPE 35 -#define SYS_DUP2 36 -#define SYS_RAISE 37 -#define SYS_KILL 38 -#define SYS_SIGNAL 39 -#define SYS_SIGNAL_DONE 40 -#define SYS_TCSETPGRP 41 -#define SYS_GET_PID 42 +#define SYS_DUP 36 +#define SYS_DUP2 37 +#define SYS_RAISE 38 +#define SYS_KILL 39 +#define SYS_SIGNAL 40 +#define SYS_SIGNAL_DONE 41 +#define SYS_TCSETPGRP 42 +#define SYS_GET_PID 43 __END_DECLS diff --git a/libc/unistd.cpp b/libc/unistd.cpp index 4f6dd6ef..d924d65a 100644 --- a/libc/unistd.cpp +++ b/libc/unistd.cpp @@ -61,6 +61,11 @@ ssize_t write(int fildes, const void* buf, size_t nbyte) return syscall(SYS_WRITE, fildes, buf, nbyte); } +int dup(int fildes) +{ + return syscall(SYS_DUP, fildes); +} + int dup2(int fildes, int fildes2) { return syscall(SYS_DUP2, fildes, fildes2);