aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2020-11-14 13:27:42 +0100
committerGitHub <noreply@github.com>2020-11-14 13:27:42 +0100
commit8e6dfded7ac1f0b04c2a0a4e6a5395613ae200eb (patch)
tree7aafdad334a5e443831a6a77efdf36b4fdc6245d /src
parentfeat(development): add --debug flag (#41) (diff)
downloadsl0ppij-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.rs1
-rw-r--r--src/os_input_output.rs32
-rw-r--r--src/tests/fakes.rs4
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(&current_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);