From 154e8f94af67e092449896012d8f2d33cb70926e Mon Sep 17 00:00:00 2001 From: FelixBrgm Date: Tue, 20 May 2025 05:40:26 +0000 Subject: [PATCH 1/3] deactivate raw mode while attach command is running inside of the shell --- src/bin/taskshell.rs | 27 ++++++++++++++++++--------- src/shell.rs | 6 +++++- src/termios.rs | 23 +++++++++++++++++++++-- 3 files changed, 44 insertions(+), 12 deletions(-) diff --git a/src/bin/taskshell.rs b/src/bin/taskshell.rs index b75fdb7..8ecec6a 100644 --- a/src/bin/taskshell.rs +++ b/src/bin/taskshell.rs @@ -8,6 +8,7 @@ use std::{ thread, time::Duration, }; +use libc::termios; use tokio::{ io::{AsyncBufReadExt, AsyncRead, AsyncWriteExt, BufReader}, net::UnixStream, @@ -21,8 +22,8 @@ use tasklib::{ }, shell::{ self, - args::{Args, EngineSubcommand, ShellCommand, help}, - }, + args::{help, Args, EngineSubcommand, ShellCommand}, + }, termios::{change_to_raw_mode, get_current_termios, 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,14 @@ 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 +247,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 +291,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 +306,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 +331,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); } } From 3fa57f51c951b8f2b553720fe37a0d03fe4966b6 Mon Sep 17 00:00:00 2001 From: FelixBrgm Date: Tue, 20 May 2025 05:42:09 +0000 Subject: [PATCH 2/3] cargo fmt --- src/bin/taskshell.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bin/taskshell.rs b/src/bin/taskshell.rs index 8ecec6a..4b2d51e 100644 --- a/src/bin/taskshell.rs +++ b/src/bin/taskshell.rs @@ -1,3 +1,4 @@ +use libc::termios; use std::{ env::args, fs, @@ -8,7 +9,6 @@ use std::{ thread, time::Duration, }; -use libc::termios; use tokio::{ io::{AsyncBufReadExt, AsyncRead, AsyncWriteExt, BufReader}, net::UnixStream, @@ -22,8 +22,9 @@ use tasklib::{ }, shell::{ self, - args::{help, Args, EngineSubcommand, ShellCommand}, - }, termios::{change_to_raw_mode, get_current_termios, reset_to_termios}, + args::{Args, EngineSubcommand, ShellCommand, help}, + }, + termios::{change_to_raw_mode, get_current_termios, reset_to_termios}, }; use tasklib::jsonrpc::request::Request; @@ -228,7 +229,6 @@ async fn attach(name: &str, socket_path: &str, to: &str, mut orig: Option<&mut l *orig = change_to_raw_mode(); } "".to_string() - } async fn response_to_str(response: &Response, orig: Option<&mut libc::termios>) -> String { From 5b644d0a6a4717c68b141bd83f174e97c518a151 Mon Sep 17 00:00:00 2001 From: FelixBrgm Date: Tue, 20 May 2025 05:44:20 +0000 Subject: [PATCH 3/3] cargo clippy --- src/bin/taskboard.rs | 4 ++-- src/bin/taskshell.rs | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) 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 4b2d51e..41440d5 100644 --- a/src/bin/taskshell.rs +++ b/src/bin/taskshell.rs @@ -1,4 +1,3 @@ -use libc::termios; use std::{ env::args, fs, @@ -24,7 +23,7 @@ use tasklib::{ self, args::{Args, EngineSubcommand, ShellCommand, help}, }, - termios::{change_to_raw_mode, get_current_termios, reset_to_termios}, + termios::{change_to_raw_mode, reset_to_termios}, }; use tasklib::jsonrpc::request::Request;