use nix::sys::termios::{SetArg, Termios, tcgetattr, tcsetattr};
use nix::unistd::isatty;
use std::os::fd::BorrowedFd;
const TTY_FD: std::os::unix::io::RawFd = 0;
pub fn capture_tty_termios() -> nix::Result<Option<Termios>> {
let fd = unsafe { BorrowedFd::borrow_raw(TTY_FD) };
if !isatty(fd)? {
return Ok(None);
}
tcgetattr(fd).map(Some)
}
pub fn apply_tty_termios(tmodes: &Termios) -> nix::Result<()> {
let fd = unsafe { BorrowedFd::borrow_raw(TTY_FD) };
if !isatty(fd)? {
return Ok(());
}
tcsetattr(fd, SetArg::TCSANOW, tmodes)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn capture_tty_termios_returns_none_when_stdin_redirected() {
let result = capture_tty_termios();
assert!(
matches!(result, Ok(None)),
"expected Ok(None) when stdin is not a TTY, got {:?}",
result
);
}
#[test]
fn apply_tty_termios_noop_when_non_tty() {
let zeroed: libc::termios = unsafe { std::mem::zeroed() };
let tmodes: nix::sys::termios::Termios = zeroed.into();
let result = apply_tty_termios(&tmodes);
assert!(
result.is_ok(),
"expected Ok(()) when stdin is not a TTY, got {:?}",
result
);
}
}