mod backend;
mod error;
mod library;
mod process;
mod program;
pub use error::{Error, Result};
pub use library::Library;
pub use process::Process;
pub use program::{Child, Program, Stdio};
pub fn inject_program(
spec: impl Into<Program>,
library: impl Into<Library>,
) -> Result<InjectedProgram> {
backend::default_backend()?.inject_program(spec.into(), library.into())
}
pub fn inject_process(process: Process, library: impl Into<Library>) -> Result<InjectedProcess> {
backend::default_backend()?.inject_process(process, library.into())
}
pub fn spawn(spec: impl Into<Program>) -> Result<SuspendedProgram> {
backend::default_backend()?.spawn(spec.into())
}
#[derive(Debug)]
pub struct SuspendedProgram {
backend: backend::BackendHandle,
process: Process,
stdio: Stdio,
}
impl SuspendedProgram {
pub(crate) fn new(backend: backend::BackendHandle, process: Process, stdio: Stdio) -> Self {
Self {
backend,
process,
stdio,
}
}
pub fn process(&self) -> Process {
self.process
}
pub fn inject(self, library: Library) -> Result<InjectedProgram> {
let injected = self.backend.inject_process(self.process, library)?;
if let Err(err) = self.backend.resume(self.process) {
let _ = injected.uninject();
return Err(err);
}
let child = Child::new(self.process, self.stdio);
Ok(injected.into_program(child))
}
pub fn resume(self) -> Result<Child> {
self.backend.resume(self.process)?;
Ok(Child::new(self.process, self.stdio))
}
}
#[derive(Debug)]
pub struct InjectedProcess {
backend: backend::BackendHandle,
id: u64,
process: Process,
}
impl InjectedProcess {
pub(crate) fn new(backend: backend::BackendHandle, id: u64, process: Process) -> Self {
Self {
backend,
id,
process,
}
}
pub fn process(&self) -> Process {
self.process
}
pub fn uninject(self) -> Result<()> {
self.backend.uninject(self.id)
}
pub(crate) fn into_program(self, child: Child) -> InjectedProgram {
InjectedProgram::new(self.backend, self.id, self.process, child)
}
}
#[derive(Debug)]
pub struct InjectedProgram {
backend: backend::BackendHandle,
id: u64,
process: Process,
child: Child,
}
impl InjectedProgram {
pub(crate) fn new(
backend: backend::BackendHandle,
id: u64,
process: Process,
child: Child,
) -> Self {
Self {
backend,
id,
process,
child,
}
}
pub fn process(&self) -> Process {
self.process
}
pub fn child(&self) -> &Child {
&self.child
}
pub fn uninject(self) -> Result<()> {
self.backend.uninject(self.id)
}
}