#![allow(dead_code)]
pub mod mock_terminal;
pub mod pty;
use std::os::unix::process::CommandExt;
use std::path::PathBuf;
use std::process::Command;
use std::sync::atomic::{AtomicU64, Ordering};
unsafe fn reset_to_default(sig: libc::c_int) -> std::io::Result<()> {
let mut sa: libc::sigaction = unsafe { std::mem::zeroed() };
sa.sa_sigaction = libc::SIG_DFL;
let rc = unsafe { libc::sigaction(sig, &sa, std::ptr::null_mut()) };
if rc != 0 {
return Err(std::io::Error::last_os_error());
}
Ok(())
}
pub fn reset_trap_signals(cmd: &mut Command) {
unsafe {
cmd.pre_exec(|| {
reset_to_default(libc::SIGINT)?;
reset_to_default(libc::SIGQUIT)?;
Ok(())
});
}
}
static TEMP_DIR_COUNTER: AtomicU64 = AtomicU64::new(0);
pub struct TempDir {
path: PathBuf,
}
impl TempDir {
pub fn new() -> Self {
let mut path = std::env::temp_dir();
let id = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_nanos();
let seq = TEMP_DIR_COUNTER.fetch_add(1, Ordering::Relaxed);
path.push(format!("yosh-test-{}-{}", id, seq));
std::fs::create_dir_all(&path).unwrap();
TempDir { path }
}
pub fn path(&self) -> &PathBuf {
&self.path
}
pub fn write_file(&self, name: &str, content: &str) -> PathBuf {
let file_path = self.path.join(name);
std::fs::write(&file_path, content).unwrap();
file_path
}
}
impl Drop for TempDir {
fn drop(&mut self) {
let _ = std::fs::remove_dir_all(&self.path);
}
}