diff --git a/src/main.rs b/src/main.rs index a30525da..8ea4da0b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,6 @@ mod os_input_output; use std::io; -use futures::future::join_all; use ::std::fmt::{self, Display, Formatter}; use std::cmp::max; use std::io::{Read, Write}; @@ -51,10 +50,10 @@ impl Stream for ReadFromPid { if *errno == nix::errno::Errno::EAGAIN { return Poll::Ready(Some(vec![])) // TODO: better with timeout waker somehow } else { - panic!("error {:?}", e); + Poll::Ready(None) } }, - _ => panic!("error {:?}", e) + _ => Poll::Ready(None) } } } @@ -654,6 +653,7 @@ enum ScreenInstruction { ResizeLeft, ResizeRight, MoveFocus, + Quit, } struct Screen { @@ -946,14 +946,14 @@ impl Screen { } enum PtyInstruction { - SpawnTerminal + SpawnTerminal, + Quit } struct PtyBus { receive_pty_instructions: Receiver, send_pty_instructions: Sender, send_screen_instructions: Sender, - active_ptys: Vec>, os_input: Box, } @@ -964,13 +964,13 @@ impl PtyBus { send_pty_instructions, send_screen_instructions, receive_pty_instructions, - active_ptys: Vec::new(), + // active_ptys: Vec::new(), os_input, } } pub fn spawn_terminal(&mut self) { let (pid_primary, _pid_secondary): (RawFd, RawFd) = self.os_input.spawn_terminal(); - let task_handle = task::spawn({ + task::spawn({ let send_screen_instructions = self.send_screen_instructions.clone(); let os_input = self.os_input.clone(); async move { @@ -989,17 +989,6 @@ impl PtyBus { } }); self.send_screen_instructions.send(ScreenInstruction::AddTerminal(pid_primary)).unwrap(); - self.active_ptys.push(task_handle); - } - pub async fn _wait_for_tasks(&mut self) { -// let task1 = self.active_ptys.get_mut(0).unwrap(); -// task1.await; - let mut v = vec![]; - for handle in self.active_ptys.iter_mut() { - // TODO: better, see commented lines above... can't we do this on the original vec? - v.push(handle); - } - join_all(v).await; } } @@ -1034,10 +1023,11 @@ fn start(os_input: OsInputOutput) { PtyInstruction::SpawnTerminal => { pty_bus.spawn_terminal(); } + PtyInstruction::Quit => { + break; + } } } - // TODO: do this when we exit - // task::block_on(pty_bus.wait_for_tasks()); } }).unwrap() ); @@ -1073,6 +1063,9 @@ fn start(os_input: OsInputOutput) { ScreenInstruction::MoveFocus => { screen.move_focus(); } + ScreenInstruction::Quit => { + break; + } } } } @@ -1096,14 +1089,19 @@ fn start(os_input: OsInputOutput) { } else if buffer[0] == 14 { // ctrl-n send_pty_instructions.send(PtyInstruction::SpawnTerminal).unwrap(); continue; + } else if buffer[0] == 17 { // ctrl-q + send_screen_instructions.send(ScreenInstruction::Quit).unwrap(); + send_pty_instructions.send(PtyInstruction::Quit).unwrap(); + break; } } send_screen_instructions.send(ScreenInstruction::WriteCharacter(buffer[0])).unwrap(); }; -// cleanup(); -// for thread_handler in active_threads { -// thread_handler.join().unwrap(); -// } + for thread_handler in active_threads { + thread_handler.join().unwrap(); + } + // cleanup(); + println!("\rBye from Mosaic!"); } diff --git a/src/os_input_output.rs b/src/os_input_output.rs index 22a507a4..1af6d5df 100644 --- a/src/os_input_output.rs +++ b/src/os_input_output.rs @@ -1,4 +1,4 @@ -use nix::unistd::{read, write, ForkResult}; +use nix::unistd::{read, write, ForkResult, Pid}; use nix::fcntl::{fcntl, FcntlArg, OFlag}; use nix::sys::termios::{ tcgetattr, @@ -7,6 +7,7 @@ use nix::sys::termios::{ SetArg, tcdrain, }; +use nix::sys::signal::kill; use nix::pty::{forkpty, Winsize}; use std::os::unix::io::RawFd; use std::process::Command; @@ -66,8 +67,8 @@ fn spawn_terminal () -> (RawFd, RawFd) { }, ForkResult::Child => { Command::new(env::var("SHELL").unwrap()).spawn().expect("failed to spawn"); - ::std::thread::park(); - todo!(); + ::std::thread::park(); // TODO: if we remove this, we seem to lose bytes from stdin - find out why + Pid::from_raw(0) // TODO: better }, }; (pid_primary, pid_secondary.as_raw()) @@ -81,12 +82,7 @@ fn spawn_terminal () -> (RawFd, RawFd) { } #[derive(Clone)] -pub struct OsInputOutput { -// pub get_terminal_size_using_fd: Box Winsize + Send>, -// pub set_terminal_size_using_fd: Box, -// pub into_raw_mode: Box, -// pub spawn_terminal: Box (RawFd, RawFd) + Send>, -} +pub struct OsInputOutput {} pub trait OsApi: Send + Sync { fn get_terminal_size_using_fd(&self, pid: RawFd) -> Winsize; @@ -96,8 +92,8 @@ pub trait OsApi: Send + Sync { fn read(&self, pid: RawFd, buf: &mut [u8]) -> Result; fn write(&self, pid: RawFd, buf: &mut [u8]) -> Result; fn tcdrain(&self, pid: RawFd) -> Result<(), nix::Error>; + fn kill(&self, pid: RawFd) -> Result<(), nix::Error>; fn box_clone(&self) -> Box; - // let read_result = read(self.pid, &mut self.read_buffer); } impl OsApi for OsInputOutput { @@ -125,6 +121,9 @@ impl OsApi for OsInputOutput { fn box_clone(&self) -> Box { Box::new((*self).clone()) } + fn kill(&self, fd: RawFd) -> Result<(), nix::Error> { + kill(Pid::from_raw(fd), None) + } } impl Clone for Box