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 <dev@notgull.net>
This commit is contained in:
John Nunley 2024-02-01 06:34:02 -08:00 committed by GitHub
parent 62430fd56e
commit 24e3691794
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 28 additions and 5 deletions

View File

@ -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)
}
}