use nix::errno::Errno; use nix::sys::wait::{waitid, Id, WaitPidFlag, WaitStatus}; use nix::unistd::Pid; pub struct DebugTarget { state: S, } pub trait DebugState { #[allow(dead_code)] fn pid(&self) -> Pid; } pub struct Stopped { pid: Pid, } impl DebugState for Stopped { fn pid(&self) -> Pid { self.pid } } impl DebugTarget { pub fn new(pid: Pid) -> Result { waitid(Id::Pid(pid), WaitPidFlag::WSTOPPED).and(Ok(DebugTarget { state: Stopped { pid } })) } pub fn cont(self) -> Result, Errno> { nix::sys::ptrace::cont(self.state.pid, None).and(Ok(DebugTarget { state: Running { pid: self.state.pid } })) } } pub struct Running { pid: Pid, } impl DebugState for Running { fn pid(&self) -> Pid { self.pid } } impl DebugTarget { pub fn wait_for_exit(self) -> Result { waitid(Id::Pid(self.state.pid), WaitPidFlag::WEXITED).and_then(|status| match status { WaitStatus::Exited(_, exit_code) => Ok(exit_code), _ => Err(Errno::EINVAL), // TODO: custom error type? }) } }