1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
use libc; use std::io::Result; use std::os::unix::io::AsRawFd; use termios::*; use ::tty; use winsize; static mut termios_to_restore: Option<Termios> = None; pub extern "C" fn restore_termios() { match unsafe { termios_to_restore } { Some(termios) => { let _ = tcsetattr(libc::STDIN_FILENO, TCSANOW, &termios); } None => (), } } pub fn setup_terminal(pty: tty::Master) -> Result<()> { let termios = try!(Termios::from_fd(libc::STDIN_FILENO)); unsafe { termios_to_restore = Some(termios); libc::atexit(restore_termios); }; try!(enter_raw_mode(libc::STDIN_FILENO)); let winsize = try!(winsize::from_fd(libc::STDIN_FILENO)); winsize::set(pty.as_raw_fd(), &winsize); Ok(()) } fn enter_raw_mode(fd: libc::c_int) -> Result<()> { let mut new_termios = try!(Termios::from_fd(fd)); new_termios.c_lflag &= !(ECHO | ICANON | IEXTEN | ISIG); new_termios.c_iflag &= !(BRKINT | ICRNL | INPCK | ISTRIP | IXON); new_termios.c_cflag &= !(CSIZE | PARENB); new_termios.c_cflag |= CS8; new_termios.c_oflag &= !(OPOST); new_termios.c_cc[VMIN] = 1; new_termios.c_cc[VTIME] = 0; try!(tcsetattr(libc::STDIN_FILENO, TCSANOW, &new_termios)); Ok(()) }