use std::sync::atomic::{AtomicBool, Ordering};
static TUI_ACTIVE: AtomicBool = AtomicBool::new(false);
pub fn set_tui_active(active: bool) {
TUI_ACTIVE.store(active, Ordering::SeqCst);
}
#[cfg(unix)]
pub fn suppress_stdio() -> Option<StdioGuard> {
use std::os::unix::io::AsRawFd;
let tui_active = TUI_ACTIVE.load(Ordering::SeqCst);
unsafe {
let stderr_fd = std::io::stderr().as_raw_fd();
let saved_stderr = libc::dup(stderr_fd);
if saved_stderr < 0 {
return None;
}
let saved_stdout = if tui_active {
-1 } else {
let stdout_fd = std::io::stdout().as_raw_fd();
let fd = libc::dup(stdout_fd);
if fd < 0 {
libc::close(saved_stderr);
return None;
}
fd
};
let devnull = libc::open(c"/dev/null".as_ptr(), libc::O_WRONLY);
if devnull < 0 {
if saved_stdout >= 0 {
libc::close(saved_stdout);
}
libc::close(saved_stderr);
return None;
}
if saved_stdout >= 0 {
libc::dup2(devnull, std::io::stdout().as_raw_fd());
}
libc::dup2(devnull, stderr_fd);
libc::close(devnull);
Some(StdioGuard {
saved_stdout,
saved_stderr,
})
}
}
#[cfg(unix)]
pub struct StdioGuard {
saved_stdout: i32, saved_stderr: i32,
}
#[cfg(unix)]
impl Drop for StdioGuard {
fn drop(&mut self) {
use std::os::unix::io::AsRawFd;
unsafe {
let stderr_fd = std::io::stderr().as_raw_fd();
libc::dup2(self.saved_stderr, stderr_fd);
libc::close(self.saved_stderr);
if self.saved_stdout >= 0 {
let stdout_fd = std::io::stdout().as_raw_fd();
libc::dup2(self.saved_stdout, stdout_fd);
libc::close(self.saved_stdout);
}
}
}
}
#[cfg(not(unix))]
pub fn suppress_stdio() -> Option<StdioGuard> {
None
}
#[cfg(not(unix))]
pub struct StdioGuard;