diff options
| author | Aram Drevekenin <aram@poor.dev> | 2020-11-14 13:27:42 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-11-14 13:27:42 +0100 |
| commit | 8e6dfded7ac1f0b04c2a0a4e6a5395613ae200eb (patch) | |
| tree | 7aafdad334a5e443831a6a77efdf36b4fdc6245d /src | |
| parent | feat(development): add --debug flag (#41) (diff) | |
| download | sl0ppij-8e6dfded7ac1f0b04c2a0a4e6a5395613ae200eb.tar.gz sl0ppij-8e6dfded7ac1f0b04c2a0a4e6a5395613ae200eb.tar.xz sl0ppij-8e6dfded7ac1f0b04c2a0a4e6a5395613ae200eb.zip | |
fix(ux): properly echo characters and do not mess up exit (#44)
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.rs | 1 | ||||
| -rw-r--r-- | src/os_input_output.rs | 32 | ||||
| -rw-r--r-- | src/tests/fakes.rs | 4 |
3 files changed, 31 insertions, 6 deletions
diff --git a/src/main.rs b/src/main.rs index becdd457..1f30d334 100644 --- a/src/main.rs +++ b/src/main.rs @@ -341,6 +341,7 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) { let goto_start_of_last_line = format!("\u{1b}[{};{}H", full_screen_ws.ws_row, 1); let goodbye_message = format!("{}\n{}Bye from Mosaic!", goto_start_of_last_line, reset_style); + os_input.unset_raw_mode(0); os_input.get_stdout_writer().write(goodbye_message.as_bytes()).unwrap(); os_input.get_stdout_writer().flush().unwrap(); } diff --git a/src/os_input_output.rs b/src/os_input_output.rs index 6363d2e6..14690cf5 100644 --- a/src/os_input_output.rs +++ b/src/os_input_output.rs @@ -1,6 +1,7 @@ use nix::unistd::{read, write, ForkResult, Pid}; use nix::fcntl::{fcntl, FcntlArg, OFlag}; use nix::sys::termios::{ + Termios, tcgetattr, cfmakeraw, tcsetattr, @@ -14,6 +15,7 @@ use std::os::unix::io::RawFd; use std::process::{Command, Child}; use std::io::{Read, Write}; use std::path::PathBuf; +use std::sync::{Arc, Mutex}; use std::env; @@ -26,6 +28,13 @@ fn into_raw_mode(pid: RawFd) { }; } +fn unset_raw_mode(pid: RawFd, mut orig_termios: Termios) { + match tcsetattr(pid, SetArg::TCSANOW, &mut orig_termios) { + Ok(_) => {}, + Err(e) => panic!("error {:?}", e) + }; +} + pub fn get_terminal_size_using_fd(fd: RawFd) -> Winsize { // TODO: do this with the nix ioctl use libc::ioctl; @@ -91,10 +100,9 @@ fn handle_command_exit(mut child: Child) { } } -fn spawn_terminal (file_to_open: Option<PathBuf>) -> (RawFd, RawFd) { +fn spawn_terminal (file_to_open: Option<PathBuf>, orig_termios: Termios) -> (RawFd, RawFd) { let (pid_primary, pid_secondary): (RawFd, RawFd) = { - let current_termios = tcgetattr(0).unwrap(); - match forkpty(None, Some(¤t_termios)) { + match forkpty(None, Some(&orig_termios)) { Ok(fork_pty_res) => { let pid_primary = fork_pty_res.master; let pid_secondary = match fork_pty_res.fork_result { @@ -134,12 +142,15 @@ fn spawn_terminal (file_to_open: Option<PathBuf>) -> (RawFd, RawFd) { } #[derive(Clone)] -pub struct OsInputOutput {} +pub struct OsInputOutput { + orig_termios: Arc<Mutex<Termios>>, +} pub trait OsApi: Send + Sync { fn get_terminal_size_using_fd(&self, pid: RawFd) -> Winsize; fn set_terminal_size_using_fd(&mut self, pid: RawFd, cols: u16, rows: u16); fn into_raw_mode(&mut self, pid: RawFd); + fn unset_raw_mode(&mut self, pid: RawFd); fn spawn_terminal(&mut self, file_to_open: Option<PathBuf>) -> (RawFd, RawFd); fn read_from_tty_stdout(&mut self, pid: RawFd, buf: &mut [u8]) -> Result<usize, nix::Error>; fn write_to_tty_stdin(&mut self, pid: RawFd, buf: &mut [u8]) -> Result<usize, nix::Error>; @@ -160,8 +171,13 @@ impl OsApi for OsInputOutput { fn into_raw_mode(&mut self, pid: RawFd) { into_raw_mode(pid); } + fn unset_raw_mode(&mut self, pid: RawFd) { + let orig_termios = self.orig_termios.lock().unwrap(); + unset_raw_mode(pid, orig_termios.clone()); + } fn spawn_terminal(&mut self, file_to_open: Option<PathBuf>) -> (RawFd, RawFd) { - spawn_terminal(file_to_open) + let orig_termios = self.orig_termios.lock().unwrap(); + spawn_terminal(file_to_open, orig_termios.clone()) } fn read_from_tty_stdout(&mut self, pid: RawFd, buf: &mut [u8]) -> Result<usize, nix::Error> { read(pid, buf) @@ -201,5 +217,9 @@ impl Clone for Box<dyn OsApi> } pub fn get_os_input () -> OsInputOutput { - OsInputOutput {} + let current_termios = tcgetattr(0).unwrap(); + let orig_termios = Arc::new(Mutex::new(current_termios)); + OsInputOutput { + orig_termios + } } diff --git a/src/tests/fakes.rs b/src/tests/fakes.rs index be43bde5..a9f34778 100644 --- a/src/tests/fakes.rs +++ b/src/tests/fakes.rs @@ -14,6 +14,7 @@ pub enum IoEvent { Kill(RawFd), SetTerminalSizeUsingFd(RawFd, u16, u16), IntoRawMode(RawFd), + UnsetRawMode(RawFd), TcDrain(RawFd), } @@ -123,6 +124,9 @@ impl OsApi for FakeInputOutput { fn into_raw_mode(&mut self, pid: RawFd) { self.io_events.lock().unwrap().push(IoEvent::IntoRawMode(pid)); } + fn unset_raw_mode(&mut self, pid: RawFd) { + self.io_events.lock().unwrap().push(IoEvent::UnsetRawMode(pid)); + } fn spawn_terminal(&mut self, _file_to_open: Option<PathBuf>) -> (RawFd, RawFd) { let next_terminal_id = { self.read_buffers.lock().unwrap().keys().len() as RawFd + 1 }; self.add_terminal(next_terminal_id); |
