diff --git a/src/bin/taskboard.rs b/src/bin/taskboard.rs index 33316d6..b3f46ae 100644 --- a/src/bin/taskboard.rs +++ b/src/bin/taskboard.rs @@ -52,7 +52,7 @@ impl TaskBoard { self.load_terminal_dimnsions(); self.clear_screen(); - let orig_termios = change_to_raw_mode(); + let mut orig_termios = change_to_raw_mode(); let mut buf: [u8; 1] = [0; 1]; @@ -72,7 +72,7 @@ impl TaskBoard { self.display_content(); } self.clear_screen(); - reset_to_termios(orig_termios); + reset_to_termios(&mut orig_termios); } fn display_content(&mut self) { diff --git a/src/bin/taskshell.rs b/src/bin/taskshell.rs index b75fdb7..41440d5 100644 --- a/src/bin/taskshell.rs +++ b/src/bin/taskshell.rs @@ -23,6 +23,7 @@ use tasklib::{ self, args::{Args, EngineSubcommand, ShellCommand, help}, }, + termios::{change_to_raw_mode, reset_to_termios}, }; use tasklib::jsonrpc::request::Request; @@ -182,7 +183,11 @@ fn build_request(command: &ShellCommand) -> BuildRequestResult { } } -async fn attach(name: &str, socket_path: &str, to: &str) -> String { +async fn attach(name: &str, socket_path: &str, to: &str, mut orig: Option<&mut libc::termios>) -> String { + if let Some(o) = orig.as_mut() { + reset_to_termios(o); + } + let (tx, mut rx) = tokio::sync::mpsc::channel::<()>(1); let tx_clone = tx.clone(); @@ -219,10 +224,13 @@ async fn attach(name: &str, socket_path: &str, to: &str) -> String { } } } + if let Some(orig) = orig { + *orig = change_to_raw_mode(); + } "".to_string() } -async fn response_to_str(response: &Response) -> String { +async fn response_to_str(response: &Response, orig: Option<&mut libc::termios>) -> String { match response.response_type() { ResponseType::Result(res) => { use tasklib::jsonrpc::response::ResponseResult::*; @@ -238,14 +246,14 @@ async fn response_to_str(response: &Response) -> String { Restart(name) => format!("restarting: {name}"), Reload => "reloading configuration".to_string(), Halt => "shutting down taskmaster".to_string(), - Attach { name, socketpath, to } => attach(name, socketpath, to).await, + Attach { name, socketpath, to } => attach(name, socketpath, to, orig).await, } } ResponseType::Error(err) => err.message.to_string(), } } -async fn handle_input(input: Vec) -> Result { +async fn handle_input(input: Vec, orig: Option<&mut libc::termios>) -> Result { let arguments = Args::try_from(input)?; let request = match build_request(arguments.command()) { @@ -282,7 +290,7 @@ async fn handle_input(input: Vec) -> Result { }; response.set_response_result(request.request_type()); - Ok(response_to_str(&response).await) + Ok(response_to_str(&response, orig).await) } fn print_raw_mode(string: &str) { @@ -297,7 +305,7 @@ fn print_raw_mode(string: &str) { async fn shell() { let mut shell = shell::Shell::new("taskshell> "); while let Some(line) = shell.next_line() { - let msg = match handle_input(line.split_ascii_whitespace().map(String::from).collect::>()).await { + let msg = match handle_input(line.split_ascii_whitespace().map(String::from).collect::>(), Some(shell.orig_mut())).await { Ok(s) => s, Err(s) => s, }; @@ -322,7 +330,7 @@ async fn main() { match args.len() { 0 => shell().await, - _ => match handle_input(args).await { + _ => match handle_input(args, None).await { Ok(data) => print_raw_mode(&format!("{data}\n")), Err(e) => { print_raw_mode(&e.to_string()); diff --git a/src/shell.rs b/src/shell.rs index b7a256c..bbe9c55 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -30,7 +30,7 @@ pub struct Shell { impl Drop for Shell { fn drop(&mut self) { - crate::termios::reset_to_termios(self.orig); + crate::termios::reset_to_termios(&mut self.orig); } } @@ -61,6 +61,10 @@ impl Shell { } } + pub fn orig_mut(&mut self) -> &mut libc::termios { + &mut self.orig + } + pub fn next_line(&mut self) -> Option { let mut waiting_for_arrow_command = false; let mut history_index = 0; diff --git a/src/termios.rs b/src/termios.rs index 78cd6f2..b65c924 100644 --- a/src/termios.rs +++ b/src/termios.rs @@ -5,6 +5,25 @@ unsafe extern "C" { unsafe fn cfmakeraw(termios: *mut termios); } +pub fn get_current_termios() -> libc::termios { + let mut orig: libc::termios = libc::termios { + c_iflag: 0, + c_oflag: 0, + c_cflag: 0, + c_lflag: 0, + c_line: 0, + c_cc: [0; NCCS], + c_ispeed: 0, + c_ospeed: 0, + }; + + unsafe { + tcgetattr(0, &raw mut orig); + } + + orig +} + pub fn change_to_raw_mode() -> libc::termios { let mut orig: libc::termios = libc::termios { c_iflag: 0, @@ -34,8 +53,8 @@ pub fn change_to_raw_mode() -> libc::termios { orig } -pub fn reset_to_termios(orig: libc::termios) { +pub fn reset_to_termios(orig: &mut libc::termios) { unsafe { - tcsetattr(0, TCSAFLUSH, &orig); + tcsetattr(0, TCSAFLUSH, orig); } }