From 24e3691794f8e654686eae2e9f296e85f590200b Mon Sep 17 00:00:00 2001 From: John Nunley Date: Thu, 1 Feb 2024 06:34:02 -0800 Subject: [PATCH] feat: Add a way to wait on process by PID This is needed to make processes work in `async-process`. Signed-off-by: John Nunley --- src/os/kqueue.rs | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/src/os/kqueue.rs b/src/os/kqueue.rs index aae36c3..5045cb4 100644 --- a/src/os/kqueue.rs +++ b/src/os/kqueue.rs @@ -4,6 +4,7 @@ use crate::sys::{mode_to_flags, SourceId}; use crate::{PollMode, Poller}; use std::io; +use std::marker::PhantomData; use std::process::Child; use std::time::Duration; @@ -171,11 +172,14 @@ impl Filter for Signal {} /// Monitor a child process. #[derive(Debug)] pub struct Process<'a> { - /// The child process to monitor. - child: &'a Child, + /// The process ID to monitor. + pid: rustix::process::Pid, /// The operation to monitor. ops: ProcessOps, + + /// Lifetime of the underlying process. + _lt: PhantomData<&'a Child>, } /// The operations that a monitored process can perform. @@ -200,7 +204,24 @@ impl<'a> Process<'a> { /// Once registered into the `Poller`, the `Child` object must outlive this filter's /// registration into the poller. pub unsafe fn new(child: &'a Child, ops: ProcessOps) -> Self { - Self { child, ops } + Self { + pid: rustix::process::Pid::from_child(child), + ops, + _lt: PhantomData, + } + } + + /// Create a `Process` from a PID. + /// + /// # Safety + /// + /// The PID must be tied to an actual child process. + pub unsafe fn from_pid(pid: std::num::NonZeroI32, ops: ProcessOps) -> Self { + Self { + pid: unsafe { rustix::process::Pid::from_raw_unchecked(pid.get()) }, + ops, + _lt: PhantomData, + } } } @@ -215,7 +236,8 @@ unsafe impl FilterSealed for Process<'_> { kqueue::Event::new( kqueue::EventFilter::Proc { - pid: rustix::process::Pid::from_child(self.child), + // SAFETY: We know that the PID is nonzero. + pid: self.pid, flags: events, }, flags | kqueue::EventFlags::RECEIPT, @@ -225,7 +247,8 @@ unsafe impl FilterSealed for Process<'_> { #[inline(always)] fn source_id(&self) -> SourceId { - SourceId::Pid(rustix::process::Pid::from_child(self.child)) + // SAFETY: We know that the PID is nonzero + SourceId::Pid(self.pid) } }