use std::convert::Infallible;
use std::io;
use std::process::Command;
mod sealed {
use std::process::Command;
pub trait Sealed {}
impl Sealed for Command {}
}
pub trait CommandExt: sealed::Sealed {
fn exec_replace(&mut self) -> io::Result<Infallible>;
}
impl CommandExt for Command {
#[cfg(unix)]
fn exec_replace(&mut self) -> io::Result<Infallible> {
use std::os::unix::process::CommandExt;
Err(self.exec())
}
#[cfg(windows)]
fn exec_replace(&mut self) -> io::Result<Infallible> {
use windows_sys::Win32::Foundation::{FALSE, TRUE};
use windows_sys::Win32::System::Console::SetConsoleCtrlHandler;
use windows_sys::core::BOOL;
unsafe extern "system" fn handler(_: u32) -> BOOL {
TRUE
}
unsafe {
if SetConsoleCtrlHandler(Some(handler), TRUE) == FALSE {
return Err(io::Error::other("failed to overwrite ctrl-c handler"));
}
}
let status = self.spawn()?.wait()?;
std::process::exit(status.code().unwrap_or(1))
}
#[cfg(not(any(unix, windows)))]
fn exec_replace(&mut self) -> io::Result<Infallible> {
Err(io::Error::other("implement `exec_replace`"))
}
}