Restoring of tty state on panic

master
itycodes 5 hours ago
parent c249c3a7bc
commit 12824e638c

@ -4,4 +4,4 @@ version = "0.1.0"
edition = "2024"
[dependencies]
libc = "0.2.181"
libc = { version = "0.2.181", features = ["extra_traits"] }

@ -1,18 +1,25 @@
pub mod reader;
use std::sync::{Arc, Mutex};
use reader::ReaderState;
fn main() {
let mut state = ReaderState::new("uwu> ");
assert!(ReaderState::init_tty().is_ok());
let state = Arc::new(Mutex::new(ReaderState::new("uwu> ")));
let state_r = state.clone();
assert!(state.lock().unwrap().init_tty().is_ok());
std::panic::set_hook(Box::new(move |_| {
let _ = state_r.lock().unwrap().restore_tty();
}));
loop {
let line = state.read_line();
let line = state.lock().unwrap().read_line();
match line {
Ok(s) => println!("{}", s),
Err(e) => {
eprintln!("Error: {:?}", e);
eprintln!("\nError: {:?}", e);
break;
}
}
}
let _ = state.lock().unwrap().restore_tty();
}

@ -8,6 +8,7 @@ pub mod esc_parse;
#[derive(Default)]
pub struct ReaderState {
saved_termios: Option<libc::termios>,
prompt: String,
line: String,
cursor: usize,
@ -63,7 +64,7 @@ impl ReaderState {
pub fn empty(&mut self) {
self.set_line(String::from(""));
}
pub fn init_tty() -> Result<(), InitTTYError> {
pub fn init_tty(&mut self) -> Result<(), InitTTYError> {
unsafe {
use libc::{isatty, termios, ECHO, ICANON, INPCK, TCSANOW, tcgetattr, tcsetattr};
if !(isatty(0) == 1) {
@ -71,12 +72,26 @@ impl ReaderState {
}
let mut termios: termios = MaybeUninit::zeroed().assume_init();
tcgetattr(0, &mut termios);
self.saved_termios = Some(termios.clone());
termios.c_lflag &= !(ECHO | ICANON);
termios.c_iflag &= !(INPCK);
tcsetattr(0, TCSANOW, &termios);
return Ok(());
}
}
pub fn restore_tty(&self) -> Result<(), ()> {
unsafe {
use libc::{tcsetattr, TCSANOW};
if self.saved_termios.is_none() {
Err(())
} else {
tcsetattr(0, TCSANOW, &self.saved_termios.unwrap());
Ok(())
}
}
}
pub fn insert_at_cursor(&mut self, txt: String) {
self.line.insert_str(self.cursor, txt.as_str());
self.cursor += txt.len();
@ -187,6 +202,7 @@ impl ReaderState {
NewLine => {
let line = self.line.clone();
self.submit_line(line.clone());
println!("{}", line);
return Ok(line)
},
CursorBack => {

Loading…
Cancel
Save