From 380db764e0c5466f1564045c7da40fdde967612c Mon Sep 17 00:00:00 2001 From: Irene Knapp Date: Sat, 16 Jan 2021 03:05:28 -0800 Subject: put the terminal in raw mode; also add a TerminalError type --- src/terminal.rs | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) (limited to 'src/terminal.rs') diff --git a/src/terminal.rs b/src/terminal.rs index 6d65c82..27e3c68 100644 --- a/src/terminal.rs +++ b/src/terminal.rs @@ -1,6 +1,12 @@ -use std::io::{self, BufRead, BufReader, Read}; +use crate::terminal::error::{TerminalError}; + +use nix::sys::termios; +use std::io::{BufRead, BufReader, Read}; +use std::os::unix::io::AsRawFd; use std::str; +pub mod error; + struct CharBufReader { reader: BufReader, @@ -17,10 +23,10 @@ impl CharBufReader { } pub fn fill_buf(&mut self) - -> std::result::Result<&str, io::Error> + -> std::result::Result<&str, TerminalError> { loop { - let byte_buffer = self.reader.fill_buf()?; + let byte_buffer = self.reader.fill_buf().map_err(error::input)?; match str::from_utf8(byte_buffer) { Err(error) => { @@ -63,13 +69,31 @@ impl CharBufReader { } +pub fn handle_input_terminal(input_stream: impl Read + AsRawFd) + -> std::result::Result<(), TerminalError> +{ + let fd = input_stream.as_raw_fd(); + let mut termios = termios::tcgetattr(fd) + .map_err(error::mode_setting)?; + termios.local_flags.insert(termios::LocalFlags::ECHO); + termios.local_flags.remove(termios::LocalFlags::ECHOCTL); + termios.local_flags.remove(termios::LocalFlags::ICANON); + termios.control_chars[termios::SpecialCharacterIndices::VMIN as usize] = 1; + termios.control_chars[termios::SpecialCharacterIndices::VTIME as usize] = 0; + termios::tcsetattr(fd, termios::SetArg::TCSANOW, &termios) + .map_err(error::mode_setting)?; + + handle_input(input_stream) +} + + pub fn handle_input(input_stream: impl Read) - -> std::result::Result<(), io::Error> + -> std::result::Result<(), TerminalError> { let reader = BufReader::new(input_stream); let mut reader = CharBufReader::new(reader); - let string = reader.fill_buf()?; + let string = reader.fill_buf().map_err(error::input)?; println!("top level {:?}", string); let n_to_consume = string.len(); -- cgit 1.4.1