Add support for dup and dup2

This commit is contained in:
LI Qing 2023-03-06 16:33:24 +08:00 committed by Tate, Hongliang Tian
parent 4d3539f5ea
commit 1f3f91567a
3 changed files with 43 additions and 0 deletions

View File

@ -58,6 +58,10 @@ impl FileTable {
fd
}
pub fn insert_at(&mut self, fd: FileDescripter, item: FileHandle) -> Option<FileHandle> {
self.table.insert(fd, item)
}
pub fn close_file(&mut self, fd: FileDescripter) -> Option<FileHandle> {
self.table.remove(&fd)
}

View File

@ -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<SyscallReturn> {
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<SyscallReturn> {
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 _))
}

View File

@ -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()),