Use tty_fd for set/get terminal attributes (#501)

This commit is contained in:
Andrea Jemmett 2020-10-24 16:38:03 +02:00 committed by GitHub
parent 4b1c857914
commit aa8436e41a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,16 +1,16 @@
//! UNIX related logic for terminal manipulation. //! UNIX related logic for terminal manipulation.
use std::{io, mem, process, sync::Mutex}; use std::{io, mem, process, sync::Mutex};
use crate::event::sys::unix::file_descriptor::FileDesc; use crate::event::sys::unix::file_descriptor::{tty_fd, FileDesc};
use lazy_static::lazy_static; use lazy_static::lazy_static;
use libc::{ use libc::{
cfmakeraw, ioctl, tcgetattr, tcsetattr, termios as Termios, winsize, STDIN_FILENO, cfmakeraw, ioctl, tcgetattr, tcsetattr, termios as Termios, winsize, STDOUT_FILENO, TCSANOW,
STDOUT_FILENO, TCSANOW, TIOCGWINSZ, TIOCGWINSZ,
}; };
use crate::error::{ErrorKind, Result}; use crate::error::{ErrorKind, Result};
use std::fs::File; use std::fs::File;
use std::os::unix::io::IntoRawFd; use std::os::unix::io::{IntoRawFd, RawFd};
lazy_static! { lazy_static! {
// Some(Termios) -> we're in the raw mode and this is the previous mode // Some(Termios) -> we're in the raw mode and this is the previous mode
@ -54,11 +54,13 @@ pub(crate) fn enable_raw_mode() -> Result<()> {
return Ok(()); return Ok(());
} }
let mut ios = get_terminal_attr()?; let tty = tty_fd()?;
let fd = tty.raw_fd();
let mut ios = get_terminal_attr(fd)?;
let original_mode_ios = ios; let original_mode_ios = ios;
raw_terminal_attr(&mut ios); raw_terminal_attr(&mut ios);
set_terminal_attr(&ios)?; set_terminal_attr(fd, &ios)?;
// Keep it last - set the original mode only if we were able to switch to the raw mode // Keep it last - set the original mode only if we were able to switch to the raw mode
*original_mode = Some(original_mode_ios); *original_mode = Some(original_mode_ios);
@ -70,7 +72,8 @@ pub(crate) fn disable_raw_mode() -> Result<()> {
let mut original_mode = TERMINAL_MODE_PRIOR_RAW_MODE.lock().unwrap(); let mut original_mode = TERMINAL_MODE_PRIOR_RAW_MODE.lock().unwrap();
if let Some(original_mode_ios) = original_mode.as_ref() { if let Some(original_mode_ios) = original_mode.as_ref() {
set_terminal_attr(original_mode_ios)?; let tty = tty_fd()?;
set_terminal_attr(tty.raw_fd(), original_mode_ios)?;
// Keep it last - remove the original mode only if we were able to switch back // Keep it last - remove the original mode only if we were able to switch back
*original_mode = None; *original_mode = None;
} }
@ -116,16 +119,16 @@ fn raw_terminal_attr(termios: &mut Termios) {
unsafe { cfmakeraw(termios) } unsafe { cfmakeraw(termios) }
} }
fn get_terminal_attr() -> Result<Termios> { fn get_terminal_attr(fd: RawFd) -> Result<Termios> {
unsafe { unsafe {
let mut termios = mem::zeroed(); let mut termios = mem::zeroed();
wrap_with_result(tcgetattr(STDIN_FILENO, &mut termios))?; wrap_with_result(tcgetattr(fd, &mut termios))?;
Ok(termios) Ok(termios)
} }
} }
fn set_terminal_attr(termios: &Termios) -> Result<bool> { fn set_terminal_attr(fd: RawFd, termios: &Termios) -> Result<bool> {
wrap_with_result(unsafe { tcsetattr(STDIN_FILENO, TCSANOW, termios) }) wrap_with_result(unsafe { tcsetattr(fd, TCSANOW, termios) })
} }
pub fn wrap_with_result(result: i32) -> Result<bool> { pub fn wrap_with_result(result: i32) -> Result<bool> {