/// Helper functions, especially to reproduce C std/posix functions use nix::errno::*; use nix::sys::termios; use nix::sys::termios::{ ControlFlags, InputFlags, LocalFlags, OutputFlags, SpecialCharacterIndices, Termios, }; use nix::Error as NixError; use std::io::Error; use std::os::unix::io::RawFd; use std::process::exit; // Redefine the posix constants for rust land pub const STDIN_FILENO: i32 = 0; // pub const STDOUT_FILENO: i32 = 1; // pub const STDERR_FILENO: i32 = 2; pub fn die(code: &Errno, msg: &str) -> ! { eprintln!("{:?} ({})", code, msg); exit(1) } pub fn get_termios(fd: RawFd) -> Termios { termios::tcgetattr(fd).unwrap() } pub fn enable_raw_mode() -> Result<(), Error> { let mut raw = get_termios(STDIN_FILENO); raw.input_flags.remove( InputFlags::BRKINT | InputFlags::IGNCR | InputFlags::IGNBRK | InputFlags::ICRNL | InputFlags::INLCR | InputFlags::INPCK | InputFlags::ISTRIP | InputFlags::IXON | InputFlags::PARMRK, ); raw.output_flags.remove(OutputFlags::OPOST); raw.local_flags.remove( LocalFlags::ECHO | LocalFlags::ECHONL | LocalFlags::ICANON | LocalFlags::IEXTEN | LocalFlags::ISIG, ); raw.control_flags .remove(ControlFlags::CSIZE | ControlFlags::PARENB); // 8 bit characters raw.control_flags |= termios::ControlFlags::CS8; raw.control_chars[SpecialCharacterIndices::VMIN as usize] = 0; raw.control_chars[SpecialCharacterIndices::VTIME as usize] = 1; match termios::tcsetattr(STDIN_FILENO, termios::SetArg::TCSAFLUSH, &raw) { Ok(()) => Ok(()), Err(e) => match e.as_errno() { Some(errno) => die(&errno, "tcsetattr"), None => panic!("Failed to enable raw mode"), }, } } pub fn disable_raw_mode(original: &Termios) -> Result<(), Error> { match termios::tcsetattr(STDIN_FILENO, termios::SetArg::TCSAFLUSH, original) { Ok(()) => Ok(()), Err(E) => match E.as_errno() { Some(errno) => die(&errno, "tcsetattr"), None => panic!("Failed to disable raw mode"), }, } }