diff --git a/src/arch/arm64/exceptions/syscall.rs b/src/arch/arm64/exceptions/syscall.rs index bcef398..5d30ac7 100644 --- a/src/arch/arm64/exceptions/syscall.rs +++ b/src/arch/arm64/exceptions/syscall.rs @@ -81,6 +81,7 @@ use crate::{ fcntl::sys_fcntl, select::{sys_ppoll, sys_pselect6}, }, + pidfd::sys_pidfd_open, prctl::sys_prctl, ptrace::{TracePoint, ptrace_stop, sys_ptrace}, sleep::{sys_clock_nanosleep, sys_nanosleep}, @@ -755,6 +756,7 @@ pub async fn handle_syscall(mut ctx: ProcessCtx) { } 0x125 => Err(KernelError::NotSupported), 0x1ae => Err(KernelError::NotSupported), + 0x1b2 => sys_pidfd_open(&ctx, arg1 as _, arg2 as _).await, 0x1b4 => sys_close_range(&ctx, arg1.into(), arg2.into(), arg3 as _).await, 0x1b7 => { sys_faccessat2( diff --git a/src/process/mod.rs b/src/process/mod.rs index 5bccf2c..c5cbe7a 100644 --- a/src/process/mod.rs +++ b/src/process/mod.rs @@ -41,6 +41,7 @@ pub mod exec; pub mod exit; pub mod fd_table; pub mod owned; +pub mod pidfd; pub mod prctl; pub mod ptrace; pub mod sleep; diff --git a/src/process/pidfd.rs b/src/process/pidfd.rs new file mode 100644 index 0000000..2bd0398 --- /dev/null +++ b/src/process/pidfd.rs @@ -0,0 +1,68 @@ +use crate::fs::fops::FileOps; +use crate::fs::open_file::OpenFile; +use crate::process::thread_group::pid::PidT; +use crate::process::{Tid, find_task_by_tid}; +use crate::sched::syscall_ctx::ProcessCtx; +use alloc::boxed::Box; +use alloc::sync::Arc; +use async_trait::async_trait; +use bitflags::bitflags; +use libkernel::error::{KernelError, Result}; +use libkernel::fs::OpenFlags; +use libkernel::memory::address::UA; + +bitflags! { + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub struct PidfdFlags: u32 { + const PIDFD_NONBLOCK = OpenFlags::O_NONBLOCK.bits(); + const PIDFD_THREAD = OpenFlags::O_EXCL.bits(); + } +} + +pub struct PidFile { + _pid: Tid, + _flags: PidfdFlags, +} + +impl PidFile { + pub fn new(pid: Tid, flags: PidfdFlags) -> Self { + Self { + _pid: pid, + _flags: flags, + } + } + + pub fn new_open_file(pid: Tid, flags: PidfdFlags) -> Arc { + let file = PidFile::new(pid, flags); + Arc::new(OpenFile::new( + Box::new(file), + OpenFlags::from_bits(flags.bits()).unwrap(), + )) + } +} + +#[async_trait] +impl FileOps for PidFile { + async fn readat(&mut self, _buf: UA, _count: usize, _offset: u64) -> Result { + Err(KernelError::InvalidValue) + } + + async fn writeat(&mut self, _buf: UA, _count: usize, _offset: u64) -> Result { + Err(KernelError::InvalidValue) + } +} + +pub async fn sys_pidfd_open(ctx: &ProcessCtx, pid: PidT, flags: u32) -> Result { + let pid = Tid::from_pid_t(pid); + let flags = PidfdFlags::from_bits(flags).ok_or(KernelError::InvalidValue)?; + if !flags.contains(PidfdFlags::PIDFD_THREAD) { + // Ensure the pid exists and is a thread group leader. + let _ = find_task_by_tid(pid).unwrap(); + } + + let file = PidFile::new_open_file(pid, flags); + + let fd = ctx.task().fd_table.lock_save_irq().insert(file)?; + + Ok(fd.as_raw() as _) +}