use std::io;
#[derive(Debug)]
pub struct RawModeGuard {
#[cfg(unix)]
original_termios: libc::termios,
}
impl RawModeGuard {
pub fn enable() -> io::Result<Self> {
#[cfg(unix)]
{
use libc::{tcgetattr, tcsetattr, termios, TCSAFLUSH};
use std::mem::MaybeUninit;
let mut original = MaybeUninit::<termios>::uninit();
#[allow(unsafe_code)]
if unsafe { tcgetattr(libc::STDIN_FILENO, original.as_mut_ptr()) } != 0 {
return Err(io::Error::last_os_error());
}
#[allow(unsafe_code)]
let original = unsafe { original.assume_init() };
let mut raw = original;
raw.c_lflag &= !(libc::ICANON | libc::ECHO);
#[allow(unsafe_code)]
if unsafe { tcsetattr(libc::STDIN_FILENO, TCSAFLUSH, &raw const raw) } != 0 {
return Err(io::Error::last_os_error());
}
Ok(Self {
original_termios: original,
})
}
#[cfg(windows)]
{
Ok(Self {})
}
}
}
impl Drop for RawModeGuard {
fn drop(&mut self) {
#[cfg(unix)]
{
#[allow(unsafe_code)]
unsafe {
let _ = libc::tcsetattr(libc::STDIN_FILENO, libc::TCSAFLUSH, &raw const self.original_termios);
}
}
}
}