From 1f3f91567a0b8029857770eb80b59a7d1ab0aa3a Mon Sep 17 00:00:00 2001 From: LI Qing Date: Mon, 6 Mar 2023 16:33:24 +0800 Subject: [PATCH] Add support for dup and dup2 --- .../libs/jinux-std/src/fs/file_table.rs | 4 +++ .../libs/jinux-std/src/syscall/dup.rs | 33 +++++++++++++++++++ .../libs/jinux-std/src/syscall/mod.rs | 6 ++++ 3 files changed, 43 insertions(+) create mode 100644 src/services/libs/jinux-std/src/syscall/dup.rs diff --git a/src/services/libs/jinux-std/src/fs/file_table.rs b/src/services/libs/jinux-std/src/fs/file_table.rs index 9b2a0c85f..5e9a91867 100644 --- a/src/services/libs/jinux-std/src/fs/file_table.rs +++ b/src/services/libs/jinux-std/src/fs/file_table.rs @@ -58,6 +58,10 @@ impl FileTable { fd } + pub fn insert_at(&mut self, fd: FileDescripter, item: FileHandle) -> Option { + self.table.insert(fd, item) + } + pub fn close_file(&mut self, fd: FileDescripter) -> Option { self.table.remove(&fd) } diff --git a/src/services/libs/jinux-std/src/syscall/dup.rs b/src/services/libs/jinux-std/src/syscall/dup.rs new file mode 100644 index 000000000..b4e36b47e --- /dev/null +++ b/src/services/libs/jinux-std/src/syscall/dup.rs @@ -0,0 +1,33 @@ +use crate::fs::file_table::FileDescripter; +use crate::log_syscall_entry; +use crate::prelude::*; + +use super::SyscallReturn; +use super::{SYS_DUP, SYS_DUP2}; + +pub fn sys_dup(old_fd: FileDescripter) -> Result { + log_syscall_entry!(SYS_DUP); + debug!("old_fd = {}", old_fd); + + let current = current!(); + let mut file_table = current.file_table().lock(); + let file = file_table.get_file(old_fd)?.clone(); + let new_fd = file_table.insert(file); + Ok(SyscallReturn::Return(new_fd as _)) +} + +pub fn sys_dup2(old_fd: FileDescripter, new_fd: FileDescripter) -> Result { + log_syscall_entry!(SYS_DUP2); + debug!("old_fd = {}, new_fd = {}", old_fd, new_fd); + + let current = current!(); + let mut file_table = current.file_table().lock(); + let file = file_table.get_file(old_fd)?.clone(); + if old_fd != new_fd { + if let Some(old_file) = file_table.insert_at(new_fd, file) { + // If the file descriptor `new_fd` was previously open, close it silently. + let _ = old_file.clean_for_close(); + } + } + Ok(SyscallReturn::Return(new_fd as _)) +} diff --git a/src/services/libs/jinux-std/src/syscall/mod.rs b/src/services/libs/jinux-std/src/syscall/mod.rs index 4dc16447a..bfb3ae1cc 100644 --- a/src/services/libs/jinux-std/src/syscall/mod.rs +++ b/src/services/libs/jinux-std/src/syscall/mod.rs @@ -8,6 +8,7 @@ use crate::syscall::chdir::{sys_chdir, sys_fchdir}; use crate::syscall::clock_nanosleep::sys_clock_nanosleep; use crate::syscall::clone::sys_clone; use crate::syscall::close::sys_close; +use crate::syscall::dup::{sys_dup, sys_dup2}; use crate::syscall::execve::sys_execve; use crate::syscall::exit::sys_exit; use crate::syscall::exit_group::sys_exit_group; @@ -66,6 +67,7 @@ mod clock_nanosleep; mod clone; mod close; mod constants; +mod dup; mod execve; mod exit; mod exit_group; @@ -167,6 +169,8 @@ define_syscall_nums!( SYS_ACCESS = 21, SYS_SCHED_YIELD = 24, SYS_MADVISE = 28, + SYS_DUP = 32, + SYS_DUP2 = 33, SYS_GETPID = 39, SYS_CLONE = 56, SYS_FORK = 57, @@ -291,6 +295,8 @@ pub fn syscall_dispatch( SYS_ACCESS => syscall_handler!(2, sys_access, args), SYS_SCHED_YIELD => syscall_handler!(0, sys_sched_yield), SYS_MADVISE => syscall_handler!(3, sys_madvise, args), + SYS_DUP => syscall_handler!(1, sys_dup, args), + SYS_DUP2 => syscall_handler!(2, sys_dup2, args), SYS_GETPID => syscall_handler!(0, sys_getpid), SYS_CLONE => syscall_handler!(5, sys_clone, args, context.clone()), SYS_FORK => syscall_handler!(0, sys_fork, context.clone()),