diff --git a/redox-rt/src/proc.rs b/redox-rt/src/proc.rs index a58c9bf064..fc4e753d84 100644 --- a/redox-rt/src/proc.rs +++ b/redox-rt/src/proc.rs @@ -1,8 +1,12 @@ use core::{fmt::Debug, mem::size_of}; use crate::{ - arch::*, auxv_defs::*, read_proc_meta, static_proc_info, RtTcb, DYNAMIC_PROC_INFO, - STATIC_PROC_INFO, + arch::*, + auxv_defs::*, + protocol::{ProcCall, ThreadCall}, + read_proc_meta, static_proc_info, + sys::{proc_call, thread_call}, + RtTcb, DYNAMIC_PROC_INFO, STATIC_PROC_INFO, }; use alloc::{boxed::Box, collections::BTreeMap, vec}; @@ -22,7 +26,7 @@ use goblin::elf64::{ use syscall::{ error::*, flag::{MapFlags, SEEK_SET}, - GrantDesc, GrantFlags, Map, ProcSchemeAttrs, SetSighandlerData, MAP_FIXED_NOREPLACE, + CallFlags, GrantDesc, GrantFlags, Map, ProcSchemeAttrs, SetSighandlerData, MAP_FIXED_NOREPLACE, MAP_SHARED, O_CLOEXEC, PAGE_SIZE, PROT_EXEC, PROT_READ, PROT_WRITE, }; @@ -410,6 +414,7 @@ where proc_control_addr: 0, }, ); + // TODO: sync with procmgr } unsafe { @@ -833,6 +838,20 @@ pub fn fork_inner(initial_rsp: *mut usize, args: &ForkArgs) -> Result { &crate::signal::current_setsighandler_struct(), )?; } + if let Some(ref proc_fd) = new_proc_fd { + proc_call( + **proc_fd, + &mut [], + CallFlags::empty(), + &[ProcCall::SyncSigPctl as usize], + )?; + } + thread_call( + *new_thr_fd, + &mut [], + CallFlags::empty(), + &[ThreadCall::SyncSigTctl as usize], + )?; } copy_env_regs(**cur_thr_fd, *new_thr_fd)?; } diff --git a/redox-rt/src/protocol.rs b/redox-rt/src/protocol.rs index 90032a5bd4..eb6023324a 100644 --- a/redox-rt/src/protocol.rs +++ b/redox-rt/src/protocol.rs @@ -40,6 +40,7 @@ pub enum ThreadCall { // TODO: replace with sendfd equivalent syscall for sending memory, or force userspace to // obtain its TCB memory from this server SyncSigTctl = 0, + SignalThread = 1, } impl ProcCall { @@ -64,6 +65,7 @@ impl ThreadCall { pub fn try_from_raw(raw: usize) -> Option { Some(match raw { 0 => Self::SyncSigTctl, + 1 => Self::SignalThread, _ => return None, }) } diff --git a/redox-rt/src/signal.rs b/redox-rt/src/signal.rs index e30504aef2..c0e29b5c23 100644 --- a/redox-rt/src/signal.rs +++ b/redox-rt/src/signal.rs @@ -7,7 +7,7 @@ use syscall::{ }; use crate::{ - arch::*, proc::FdGuard, protocol::ThreadCall, sync::Mutex, sys::thread_call, RtTcb, Tcb, + arch::*, proc::FdGuard, protocol::ThreadCall, sync::Mutex, sys::this_thread_call, RtTcb, Tcb, }; #[cfg(target_arch = "x86_64")] @@ -578,7 +578,7 @@ pub fn setup_sighandler(tcb: &RtTcb) { syscall::dup(**tcb.thread_fd(), b"sighandler").expect("failed to open sighandler fd"), ); let _ = syscall::write(*fd, &data).expect("failed to write to sighandler fd"); - thread_call( + this_thread_call( &mut [], CallFlags::empty(), &[ThreadCall::SyncSigTctl as usize], diff --git a/redox-rt/src/sys.rs b/redox-rt/src/sys.rs index 85d37932cd..e7794cf36e 100644 --- a/redox-rt/src/sys.rs +++ b/redox-rt/src/sys.rs @@ -12,7 +12,7 @@ use syscall::{ use crate::{ arch::manually_enter_trampoline, proc::FdGuard, - protocol::{ProcCall, ProcKillTarget, WaitFlags}, + protocol::{ProcCall, ProcKillTarget, ThreadCall, WaitFlags}, signal::tmp_disable_signals, DynamicProcInfo, RtTcb, Tcb, DYNAMIC_PROC_INFO, }; @@ -51,7 +51,7 @@ pub fn posix_write(fd: usize, buf: &[u8]) -> Result { #[inline] pub fn posix_kill(target: ProcKillTarget, sig: usize) -> Result<()> { match wrapper(false, || { - proc_call( + this_proc_call( &mut [], CallFlags::empty(), &[ProcCall::Kill as usize, target.raw(), sig], @@ -70,7 +70,7 @@ pub fn posix_sigqueue(pid: usize, sig: usize, arg: usize) -> Result<()> { pid: posix_getpid(), }; match wrapper(false, || { - proc_call( + this_proc_call( &mut siginf, CallFlags::empty(), &[ProcCall::Sigq as usize, pid, sig], @@ -133,11 +133,27 @@ pub fn sys_call( ) } } -pub fn proc_call(payload: &mut [u8], flags: CallFlags, metadata: &[usize]) -> Result { - sys_call(**crate::current_proc_fd(), payload, flags, metadata) +pub fn this_proc_call(payload: &mut [u8], flags: CallFlags, metadata: &[usize]) -> Result { + proc_call(**crate::current_proc_fd(), payload, flags, metadata) } -pub fn thread_call(payload: &mut [u8], flags: CallFlags, metadata: &[usize]) -> Result { - sys_call(**RtTcb::current().thread_fd(), payload, flags, metadata) +pub fn proc_call( + proc_fd: usize, + payload: &mut [u8], + flags: CallFlags, + metadata: &[usize], +) -> Result { + sys_call(proc_fd, payload, flags, metadata) +} +pub fn thread_call( + thread_fd: usize, + payload: &mut [u8], + flags: CallFlags, + metadata: &[usize], +) -> Result { + sys_call(thread_fd, payload, flags, metadata) +} +pub fn this_thread_call(payload: &mut [u8], flags: CallFlags, metadata: &[usize]) -> Result { + thread_call(**RtTcb::current().thread_fd(), payload, flags, metadata) } #[derive(Clone, Copy, Debug)] @@ -168,7 +184,7 @@ pub fn sys_waitpid(target: WaitpidTarget, status: &mut usize, flags: WaitFlags) WaitpidTarget::ProcGroup { pgid } => (ProcCall::Waitpgid, pgid), }; wrapper(true, || { - proc_call( + this_proc_call( unsafe { plain::as_mut_bytes(status) }, CallFlags::empty(), &[call as usize, pid, flags.bits() as usize], @@ -176,8 +192,14 @@ pub fn sys_waitpid(target: WaitpidTarget, status: &mut usize, flags: WaitFlags) }) } pub fn posix_kill_thread(thread_fd: usize, signal: u32) -> Result<()> { - let killfd = FdGuard::new(syscall::dup(thread_fd, b"signal")?); - match wrapper(false, || syscall::write(*killfd, &signal.to_ne_bytes())) { + match wrapper(false, || { + thread_call( + thread_fd, + &mut [], + CallFlags::empty(), + &[ThreadCall::SignalThread as usize, signal as usize], + ) + }) { Ok(_) | Err(Error { errno: EINTR }) => Ok(()), Err(error) => Err(error), } @@ -228,7 +250,7 @@ pub fn posix_setresugid(ids: &Resugid>) -> Result<()> { ids.sgid.unwrap_or(u32::MAX), ]); - proc_call( + this_proc_call( &mut buf, CallFlags::empty(), &[ProcCall::SetResugid as usize], @@ -276,7 +298,7 @@ pub fn posix_getresugid() -> Resugid { } } pub fn posix_exit(status: i32) -> ! { - proc_call( + this_proc_call( &mut [], CallFlags::empty(), &[ProcCall::Exit as usize, status as usize], @@ -285,7 +307,7 @@ pub fn posix_exit(status: i32) -> ! { unreachable!() } pub fn setrens(rns: usize, ens: usize) -> Result<()> { - proc_call( + this_proc_call( &mut [], CallFlags::empty(), &[ProcCall::Setrens as usize, rns, ens], @@ -293,7 +315,7 @@ pub fn setrens(rns: usize, ens: usize) -> Result<()> { Ok(()) } pub fn posix_getpgid(pid: usize) -> Result { - proc_call( + this_proc_call( &mut [], CallFlags::empty(), &[ProcCall::Setpgid as usize, pid, usize::wrapping_neg(1)], @@ -303,7 +325,7 @@ pub fn posix_setpgid(pid: usize, pgid: usize) -> Result<()> { if pgid == usize::wrapping_neg(1) { return Err(Error::new(EINVAL)); } - proc_call( + this_proc_call( &mut [], CallFlags::empty(), &[ProcCall::Setpgid as usize, pid, pgid], @@ -311,13 +333,13 @@ pub fn posix_setpgid(pid: usize, pgid: usize) -> Result<()> { Ok(()) } pub fn posix_getsid(pid: usize) -> Result { - proc_call( + this_proc_call( &mut [], CallFlags::empty(), &[ProcCall::Getsid as usize, pid], ) } pub fn posix_setsid() -> Result<()> { - proc_call(&mut [], CallFlags::empty(), &[ProcCall::Setsid as usize])?; + this_proc_call(&mut [], CallFlags::empty(), &[ProcCall::Setsid as usize])?; Ok(()) } diff --git a/src/platform/mod.rs b/src/platform/mod.rs index d5d4a69b40..611d32ba4b 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -336,7 +336,7 @@ pub unsafe fn init(auxvs: Box<[[usize; 2]]>) { redox_rt::initialize(FdGuard::new(proc_fd)); // TODO: Is it safe to assume setup_sighandler has been called at this point? - redox_rt::sys::proc_call( + redox_rt::sys::this_proc_call( &mut [], syscall::CallFlags::empty(), &[redox_rt::protocol::ProcCall::SyncSigPctl as usize],