use crate::errors::{Result, StandbyError};
use crate::signals::Signal;
use nix::sys::signal as nix_signal;
use nix::unistd::Pid;
use std::process::Child;
use std::time::{Duration, Instant};
pub fn send_signal(child: &Child, signal: Signal) -> Result<()> {
let pid = Pid::from_raw(child.id() as i32);
let nix_sig = match signal {
Signal::Term => nix_signal::Signal::SIGTERM,
Signal::Kill => nix_signal::Signal::SIGKILL,
Signal::Int => nix_signal::Signal::SIGINT,
Signal::Stop => nix_signal::Signal::SIGSTOP,
Signal::Cont => nix_signal::Signal::SIGCONT,
Signal::Tstp => nix_signal::Signal::SIGTSTP,
Signal::Hup => nix_signal::Signal::SIGHUP,
};
nix_signal::kill(pid, nix_sig).map_err(|e| StandbyError::SignalError(e.to_string()))
}
pub fn wait_with_timeout(
mut child: Child,
timeout: Option<Duration>,
) -> Result<std::process::ExitStatus> {
let start = Instant::now();
loop {
match child.try_wait() {
Ok(Some(status)) => return Ok(status),
Ok(None) => {
if let Some(timeout) = timeout
&& start.elapsed() >= timeout
{
return Err(StandbyError::ProcessError("Process timeout".to_string()));
}
std::thread::sleep(Duration::from_millis(10));
}
Err(e) => {
return Err(StandbyError::ProcessError(format!(
"Failed to wait for process: {}",
e
)));
}
}
}
}