From 88848c25fe83172faf4bcefeafc2a1fcf12cdf9d Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Sun, 30 Mar 2025 01:13:18 +0100 Subject: [PATCH] Add (backend todo) proc calls for kill+sigq. --- redox-rt/src/protocol.rs | 36 ++++++++++++++++++++ redox-rt/src/sys.rs | 61 ++++++++++++++++++++++------------ src/platform/redox/libredox.rs | 4 +-- src/platform/redox/mod.rs | 22 +++++------- src/platform/redox/signal.rs | 9 +++-- 5 files changed, 93 insertions(+), 39 deletions(-) diff --git a/redox-rt/src/protocol.rs b/redox-rt/src/protocol.rs index 7ea959b702..69b21ad3f0 100644 --- a/redox-rt/src/protocol.rs +++ b/redox-rt/src/protocol.rs @@ -22,6 +22,11 @@ pub enum ProcCall { Exit = 2, Waitpgid = 3, SetResugid = 4, + Setpgid = 5, + Getsid = 6, + Setsid = 7, + Kill = 8, + Sigq = 9, } impl ProcCall { @@ -31,6 +36,12 @@ impl ProcCall { 1 => Self::Setrens, 2 => Self::Exit, 3 => Self::Waitpgid, + 4 => Self::SetResugid, + 5 => Self::Setpgid, + 6 => Self::Getsid, + 7 => Self::Setsid, + 8 => Self::Kill, + 9 => Self::Sigq, _ => return None, }) } @@ -83,3 +94,28 @@ pub fn wexitstatus(status: usize) -> usize { pub fn wcoredump(status: usize) -> bool { (status & 0x80) != 0 } +#[derive(Clone, Copy, Debug)] +pub enum KillTarget { + SingleProc(usize), + ProcGroup(usize), + All, +} +impl KillTarget { + pub fn raw(self) -> usize { + match self { + Self::SingleProc(p) => p, + Self::ProcGroup(g) => usize::wrapping_neg(g), + Self::All => usize::wrapping_neg(1), + } + } + pub fn from_raw(raw: usize) -> Self { + let raw = raw as isize; + if raw == -1 { + Self::All + } else if raw < 0 { + Self::ProcGroup(raw as usize) + } else { + Self::SingleProc(raw as usize) + } + } +} diff --git a/redox-rt/src/sys.rs b/redox-rt/src/sys.rs index 8ac95c9288..fe6fb7cfee 100644 --- a/redox-rt/src/sys.rs +++ b/redox-rt/src/sys.rs @@ -6,13 +6,13 @@ use core::{ use syscall::{ error::{Error, Result, EINTR}, - CallFlags, RtSigInfo, TimeSpec, + CallFlags, RtSigInfo, TimeSpec, EINVAL, }; use crate::{ arch::manually_enter_trampoline, proc::FdGuard, - protocol::{ProcCall, WaitFlags}, + protocol::{KillTarget, ProcCall, WaitFlags}, signal::tmp_disable_signals, Tcb, DYNAMIC_PROC_INFO, }; @@ -49,23 +49,32 @@ pub fn posix_write(fd: usize, buf: &[u8]) -> Result { wrapper(true, || syscall::write(fd, buf)) } #[inline] -pub fn posix_kill(pid: usize, sig: usize) -> Result<()> { - match wrapper(false, || Ok(todo!("kill"))) { +pub fn posix_kill(target: KillTarget, sig: usize) -> Result<()> { + match wrapper(false, || { + proc_call( + &mut [], + CallFlags::empty(), + &[ProcCall::Kill as usize, target.raw(), sig], + ) + }) { Ok(_) | Err(Error { errno: EINTR }) => Ok(()), Err(error) => Err(error), } } #[inline] pub fn posix_sigqueue(pid: usize, sig: usize, arg: usize) -> Result<()> { - let siginf = RtSigInfo { + let mut siginf = RtSigInfo { arg, code: -1, // TODO: SI_QUEUE constant uid: 0, // TODO pid: posix_getpid(), }; - match wrapper(false, || unsafe { - //syscall::syscall3(syscall::SYS_SIGENQUEUE, pid, sig, addr_of!(siginf) as usize) - Ok(todo!("sigenqueue")) + match wrapper(false, || { + proc_call( + &mut siginf, + CallFlags::empty(), + &[ProcCall::Sigq as usize, pid, sig], + ) }) { Ok(_) | Err(Error { errno: EINTR }) => Ok(()), Err(error) => Err(error), @@ -82,16 +91,6 @@ pub fn posix_getppid() -> u32 { unsafe { addr_of!((*crate::STATIC_PROC_INFO.get()).ppid).read() } } #[inline] -pub fn posix_killpg(pgrp: usize, sig: usize) -> Result<()> { - match wrapper(false, || - //syscall::kill(usize::wrapping_neg(pgrp), sig) - Ok(todo!("killpg"))) - { - Ok(_) | Err(Error { errno: EINTR }) => Ok(()), - Err(error) => Err(error), - } -} -#[inline] pub unsafe fn sys_futex_wait(addr: *mut u32, val: u32, deadline: Option<&TimeSpec>) -> Result<()> { wrapper(true, || { syscall::syscall5( @@ -271,11 +270,31 @@ pub fn setrens(rns: usize, ens: usize) -> Result<()> { Ok(()) } pub fn posix_getpgid(pid: usize) -> Result { - todo!("posix_getpgid") + proc_call( + &mut [], + CallFlags::empty(), + &[ProcCall::Setpgid as usize, pid, usize::wrapping_neg(1)], + ) } pub fn posix_setpgid(pid: usize, pgid: usize) -> Result<()> { - todo!("posix_setpgid") + if pgid == usize::wrapping_neg(1) { + return Err(Error::new(EINVAL)); + } + proc_call( + &mut [], + CallFlags::empty(), + &[ProcCall::Setpgid as usize, pid, pgid], + )?; + Ok(()) } pub fn posix_getsid(pid: usize) -> Result { - todo!("posix_getsid") + proc_call( + &mut [], + CallFlags::empty(), + &[ProcCall::Getsid as usize, pid], + ) +} +pub fn posix_setsid() -> Result<()> { + proc_call(&mut [], CallFlags::empty(), &[ProcCall::Setsid as usize])?; + Ok(()) } diff --git a/src/platform/redox/libredox.rs b/src/platform/redox/libredox.rs index 2324e38afd..5ac31de675 100644 --- a/src/platform/redox/libredox.rs +++ b/src/platform/redox/libredox.rs @@ -1,7 +1,7 @@ use core::{slice, str}; use redox_rt::{ - protocol::WaitFlags, + protocol::{KillTarget, WaitFlags}, sys::{posix_read, posix_write, WaitpidTarget}, }; use syscall::{Error, Result, EMFILE}; @@ -259,7 +259,7 @@ pub unsafe extern "C" fn redox_waitpid_v1(pid: usize, status: *mut i32, options: #[no_mangle] pub unsafe extern "C" fn redox_kill_v1(pid: usize, signal: u32) -> RawResult { - Error::mux(redox_rt::sys::posix_kill(pid, signal as usize).map(|()| 0)) + Error::mux(redox_rt::sys::posix_kill(KillTarget::from_raw(pid), signal as usize).map(|()| 0)) } #[no_mangle] diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs index 50faa29ce4..c2fee23574 100644 --- a/src/platform/redox/mod.rs +++ b/src/platform/redox/mod.rs @@ -839,7 +839,8 @@ impl Pal for Sys { } fn setpgid(pid: pid_t, pgid: pid_t) -> Result<()> { - Ok(redox_rt::sys::posix_setpgid(pid as usize, pgid as usize)?) + redox_rt::sys::posix_setpgid(pid as usize, pgid as usize)?; + Ok(()) } fn setpriority(which: c_int, who: id_t, prio: c_int) -> Result<()> { @@ -852,37 +853,32 @@ impl Pal for Sys { } fn setsid() -> Result<()> { - let session_id = Self::getpid(); - assert!(session_id >= 0); - let mut file = File::open( - c"/scheme/thisproc/current/session_id".into(), - fcntl::O_WRONLY | fcntl::O_CLOEXEC, - )?; - file.write(&usize::to_ne_bytes(session_id.try_into().unwrap())) - .map_err(|err| Errno(err.raw_os_error().unwrap_or(EIO)))?; + redox_rt::sys::posix_setsid()?; Ok(()) } fn setresgid(rgid: gid_t, egid: gid_t, sgid: gid_t) -> Result<()> { - Ok(redox_rt::sys::posix_setresugid( + redox_rt::sys::posix_setresugid( None, None, None, cvt_uid(rgid)?, cvt_uid(egid)?, cvt_uid(sgid)?, - )?) + )?; + Ok(()) } fn setresuid(ruid: uid_t, euid: uid_t, suid: uid_t) -> Result<()> { - Ok(redox_rt::sys::posix_setresugid( + redox_rt::sys::posix_setresugid( cvt_uid(ruid)?, cvt_uid(euid)?, cvt_uid(suid)?, None, None, None, - )?) + )?; + Ok(()) } fn symlink(path1: CStr, path2: CStr) -> Result<()> { diff --git a/src/platform/redox/signal.rs b/src/platform/redox/signal.rs index e4a16c9443..5cee8745e2 100644 --- a/src/platform/redox/signal.rs +++ b/src/platform/redox/signal.rs @@ -18,6 +18,7 @@ use crate::{ use core::mem::{self, offset_of}; use redox_rt::{ proc::FdGuard, + protocol::KillTarget, signal::{ PosixStackt, SigStack, Sigaction, SigactionFlags, SigactionKind, Sigaltstack, SignalHandler, }, @@ -65,7 +66,7 @@ impl PalSignal for Sys { } fn kill(pid: pid_t, sig: c_int) -> Result<()> { - redox_rt::sys::posix_kill(pid as usize, sig as usize)?; + redox_rt::sys::posix_kill(KillTarget::from_raw(pid as usize), sig as usize)?; Ok(()) } fn sigqueue(pid: pid_t, sig: c_int, val: sigval) -> Result<()> { @@ -77,8 +78,10 @@ impl PalSignal for Sys { } fn killpg(pgrp: pid_t, sig: c_int) -> Result<()> { - redox_rt::sys::posix_killpg(pgrp as usize, sig as usize)?; - Ok(()) + if pgrp == 1 { + return Err(Errno(EINVAL)); + } + Self::kill(-pgrp, sig) } fn raise(sig: c_int) -> Result<()> {