From b4d42897d8ebcdbdd2c9efee495d587c11b5b7fc Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Fri, 11 Apr 2025 16:09:56 +0200 Subject: [PATCH] Return ERESTART when caller kills itself. --- src/procmgr.rs | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/src/procmgr.rs b/src/procmgr.rs index 6547bb389d..81d32de135 100644 --- a/src/procmgr.rs +++ b/src/procmgr.rs @@ -31,8 +31,8 @@ use syscall::{ sig_bit, ContextStatus, ContextVerb, Error, Event, EventFlags, FobtainFdFlags, MapFlags, ProcSchemeAttrs, Result, RtSigInfo, SenderInfo, SetSighandlerData, SigProcControl, Sigcontrol, EAGAIN, EBADF, EBADFD, ECHILD, EEXIST, EINTR, EINVAL, EIO, ENOENT, ENOSYS, EOPNOTSUPP, EPERM, - ESRCH, EWOULDBLOCK, O_CLOEXEC, O_CREAT, PAGE_SIZE, SIGCHLD, SIGCONT, SIGKILL, SIGSTOP, SIGTSTP, - SIGTTIN, SIGTTOU, + ERESTART, ESRCH, EWOULDBLOCK, O_CLOEXEC, O_CREAT, PAGE_SIZE, SIGCHLD, SIGCONT, SIGKILL, + SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, }; #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] @@ -880,8 +880,6 @@ impl<'a> ProcScheme<'a> { else { return Response::ready_err(EINVAL, op); }; - let mut killed_self = false; - let mode = match verb { ProcCall::Kill => KillMode::Idempotent, ProcCall::Sigq => KillMode::Queued({ @@ -895,7 +893,6 @@ impl<'a> ProcScheme<'a> { _ => unreachable!(), }; - let is_sigchld_to_parent = false; Ready(Response::new( self.on_kill(fd_pid, target, signal, mode, awoken) .map(|()| 0), @@ -1451,9 +1448,12 @@ impl<'a> ProcScheme<'a> { signal: u8, awoken: &mut VecDeque, ) -> Result<()> { - let mut killed_self = false; // TODO + let mut killed_self = false; + let is_sigchld_to_parent = false; + let caller_pid = thread.borrow().pid; // TODO: allow this to be specified? + self.on_send_sig( caller_pid, KillTarget::Thread(Rc::clone(thread)), @@ -1462,7 +1462,14 @@ impl<'a> ProcScheme<'a> { KillMode::Idempotent, is_sigchld_to_parent, awoken, - ) + )?; + + if killed_self { + // TODO: is this the most accurate error code? + Err(Error::new(ERESTART)) + } else { + Ok(()) + } } pub fn on_kill( &mut self, @@ -1475,8 +1482,12 @@ impl<'a> ProcScheme<'a> { log::trace!("KILL(from {caller_pid:?}) TARGET {target:?} {signal} {mode:?}"); let mut num_succeeded = 0; - let mut killed_self = false; // TODO - let is_sigchld_to_parent = false; // TODO + // if this is set and we would otherwise have succeeded, return EINTR so it can check its + // own mask + let mut killed_self = false; + + // SIGCHLD to parent are not generated by on_kill, but by on_send_sig itself + let is_sigchld_to_parent = false; let match_grp = match target { ProcKillTarget::SingleProc(pid) => { @@ -1522,7 +1533,11 @@ impl<'a> ProcScheme<'a> { } } - Ok(()) + if killed_self { + Err(Error::new(ERESTART)) + } else { + Ok(()) + } } pub fn on_send_sig( &self, @@ -1567,9 +1582,11 @@ impl<'a> ProcScheme<'a> { } let result = (|| { - // FIXME - let is_self = false; - //let is_self = context::is_current(&context_lock); + // XXX: It's not currently possible for procmgr to know what thread called, so the + // EINTR will be coarser. That shouldn't affect program logic though, since the + // trampoline always checks the masks anyway. + // TODO: allow regular kill (alongside thread-kill) to operate on *thread fds*? + let is_self = target_pid == caller_pid; // If sig = 0, test that process exists and can be signalled, but don't send any // signal.