Skip to content

Commit

Permalink
Merge pull request #53 from Josen-B/x86_ZLMediaKit
Browse files Browse the repository at this point in the history
add sys_dup2 and sys_dup3
  • Loading branch information
Azure-stars authored May 31, 2024
2 parents c867b9c + 0dfe1b3 commit cd24ded
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 9 deletions.
33 changes: 33 additions & 0 deletions api/arceos_posix_api/src/imp/fd_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,39 @@ pub fn sys_dup2(old_fd: c_int, new_fd: c_int) -> c_int {
})
}

/// Duplicate a file descriptor.
pub fn sys_dup3(old_fd: c_int, new_fd: c_int, flags: c_int) -> c_int {
debug!(
"sys_dup3 <= old_fd: {}, new_fd: {}, flags: {}",
old_fd, new_fd, flags
);
syscall_body!(sys_dup3, {
if old_fd == new_fd {
let r = sys_fcntl(old_fd, ctypes::F_GETFD as _, 0);
if r >= 0 {
return Ok(old_fd);
} else {
return Ok(r);
}
}
if new_fd as usize >= AX_FILE_LIMIT {
return Err(LinuxError::EBADF);
}

let f = get_file_like(old_fd)?;
FD_TABLE
.write()
.add_at(new_fd as usize, f)
.ok_or(LinuxError::EMFILE)?;

if (flags & (ctypes::O_CLOEXEC as c_int)) != 0 {
let res = sys_fcntl(new_fd, ctypes::F_SETFD as _, ctypes::FD_CLOEXEC as _);
}

Ok(new_fd)
})
}

/// Manipulate file descriptor.
///
/// TODO: `SET/GET` command is ignored, hard-code stdin/stdout
Expand Down
2 changes: 1 addition & 1 deletion api/arceos_posix_api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub use imp::task::{sys_exit, sys_getpid, sys_sched_yield};
pub use imp::time::{sys_clock_gettime, sys_nanosleep};

#[cfg(feature = "fd")]
pub use imp::fd_ops::{sys_close, sys_dup, sys_dup2, sys_fcntl};
pub use imp::fd_ops::{sys_close, sys_dup, sys_dup2, sys_dup3, sys_fcntl};
#[cfg(feature = "fs")]
pub use imp::fs::{sys_fstat, sys_getcwd, sys_lseek, sys_lstat, sys_open, sys_rename, sys_stat};
#[cfg(feature = "select")]
Expand Down
2 changes: 1 addition & 1 deletion ulib/axlibc/src/fd_ops.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{ctypes, utils::e};
use arceos_posix_api::{sys_close, sys_dup, sys_dup2, sys_fcntl};
use arceos_posix_api::{sys_close, sys_dup, sys_dup2, sys_dup3, sys_fcntl};
use axerrno::LinuxError;
use core::ffi::c_int;

Expand Down
2 changes: 2 additions & 0 deletions ulib/axstarry/src/ctypes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use axhal::{
};
use bitflags::*;
use core::panic;
/// a flag used in sys_dup3
pub const O_CLOEXEC: u32 = 524288;
/// The nano seconds number per second
pub const NSEC_PER_SEC: usize = 1_000_000_000;
bitflags! {
Expand Down
47 changes: 40 additions & 7 deletions ulib/axstarry/src/syscall_fs/imp/io.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! 负责与 IO 相关的系统调用
extern crate alloc;
use crate::ctypes;
use crate::syscall_net::Socket;
use crate::{IoVec, SyscallError, SyscallResult};
use alloc::string::ToString;
Expand Down Expand Up @@ -299,17 +300,47 @@ pub fn syscall_dup(args: [usize; 6]) -> SyscallResult {
/// 返回值:成功执行,返回新的文件描述符。失败,返回-1。
#[cfg(target_arch = "x86_64")]
pub fn syscall_dup2(args: [usize; 6]) -> SyscallResult {
syscall_dup3(args)
let fd = args[0];
let new_fd = args[1];
let process = current_process();
let mut fd_table = process.fd_manager.fd_table.lock();
if fd >= fd_table.len() {
debug!("fd {} is out of range", fd);
return Err(SyscallError::EPERM);
}
if fd_table[fd].is_none() {
debug!("fd {} is not opened", fd);
return Err(SyscallError::EPERM);
}
if new_fd >= fd_table.len() {
if new_fd >= (process.fd_manager.get_limit() as usize) {
// 超出了资源限制
return Err(SyscallError::EBADF);
}
for _i in fd_table.len()..new_fd + 1 {
fd_table.push(None);
}
}
// if process_inner.fd_manager.fd_table[new_fd].is_some() {
// debug!("new_fd {} is already opened", new_fd);
// return ErrorNo::EINVAL as isize;
// }
info!("dup2 fd {} to new fd {}", fd, new_fd);
// 就算new_fd已经被打开了,也可以被重新替代掉
fd_table[new_fd] = fd_table[fd].clone();
Ok(new_fd as isize)
}

/// 功能:复制文件描述符,并指定了新的文件描述符;
/// # Arguments
/// * fd: usize, 原文件所在的文件描述符
/// * new_fd: usize, 新的文件描述符
/// * flags: usize, 文件描述符标志
/// 返回值:成功执行,返回新的文件描述符。失败,返回-1。
pub fn syscall_dup3(args: [usize; 6]) -> SyscallResult {
let fd = args[0];
let new_fd = args[1];
let flags = args[2];
let process = current_process();
let mut fd_table = process.fd_manager.fd_table.lock();
if fd >= fd_table.len() {
Expand All @@ -320,6 +351,10 @@ pub fn syscall_dup3(args: [usize; 6]) -> SyscallResult {
debug!("fd {} is not opened", fd);
return Err(SyscallError::EPERM);
}
if fd == new_fd {
debug!("oldfd is equal to newfd");
return Err(SyscallError::EINVAL);
}
if new_fd >= fd_table.len() {
if new_fd >= (process.fd_manager.get_limit() as usize) {
// 超出了资源限制
Expand All @@ -329,13 +364,11 @@ pub fn syscall_dup3(args: [usize; 6]) -> SyscallResult {
fd_table.push(None);
}
}
// if process_inner.fd_manager.fd_table[new_fd].is_some() {
// debug!("new_fd {} is already opened", new_fd);
// return ErrorNo::EINVAL as isize;
// }
info!("dup3 fd {} to new fd {}", fd, new_fd);
// 就算new_fd已经被打开了,也可以被重新替代掉
info!("dup3 fd {} to new fd {} with flags {}", fd, new_fd, flags);
fd_table[new_fd] = fd_table[fd].clone();
if flags as u32 & ctypes::O_CLOEXEC != 0 {
fd_table[new_fd].as_mut().unwrap().set_close_on_exec(true);
}
Ok(new_fd as isize)
}

Expand Down

0 comments on commit cd24ded

Please sign in to comment.