fix(gui): kill child on block stop (#2288)

This commit is contained in:
Ellie Huxtable 2024-07-16 20:32:18 +01:00 committed by GitHub
parent 0e7f9b29d2
commit 39824db32a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 18 additions and 9 deletions

View File

@ -12,6 +12,7 @@ pub struct Pty {
pub master: Arc<Mutex<Box<dyn MasterPty + Send>>>, pub master: Arc<Mutex<Box<dyn MasterPty + Send>>>,
pub reader: Arc<Mutex<Box<dyn std::io::Read + Send>>>, pub reader: Arc<Mutex<Box<dyn std::io::Read + Send>>>,
pub child: Arc<Mutex<Box<dyn portable_pty::Child + Send>>>,
} }
impl Pty { impl Pty {
@ -29,15 +30,8 @@ impl Pty {
let cmd = CommandBuilder::new_default_prog(); let cmd = CommandBuilder::new_default_prog();
tokio::task::spawn_blocking(move || { let child = pair.slave.spawn_command(cmd).unwrap();
let mut child = pair.slave.spawn_command(cmd).unwrap(); drop(pair.slave);
// Wait for the child to exit
let _ = child.wait().unwrap();
// Ensure slave is dropped
// This closes file handles, we can deadlock if this is not done correctly.
drop(pair.slave);
});
// Handle input -> write to master writer // Handle input -> write to master writer
let (master_tx, mut master_rx) = tokio::sync::mpsc::channel::<Bytes>(32); let (master_tx, mut master_rx) = tokio::sync::mpsc::channel::<Bytes>(32);
@ -66,6 +60,7 @@ impl Pty {
tx: master_tx, tx: master_tx,
master: Arc::new(Mutex::new(pair.master)), master: Arc::new(Mutex::new(pair.master)),
reader: Arc::new(Mutex::new(reader)), reader: Arc::new(Mutex::new(reader)),
child: Arc::new(Mutex::new(child)),
}) })
} }
@ -109,4 +104,17 @@ impl Pty {
self.send_bytes(bytes).await self.send_bytes(bytes).await
} }
pub async fn kill_child(&self) -> Result<()> {
let mut child = self
.child
.lock()
.map_err(|e| eyre!("Failed to lock pty child: {e}"))?;
child
.kill()
.map_err(|e| eyre!("Failed to kill child: {e}"))?;
Ok(())
}
} }

View File

@ -87,6 +87,7 @@ pub(crate) async fn pty_kill(
state: tauri::State<'_, AtuinState>, state: tauri::State<'_, AtuinState>,
) -> Result<(), String> { ) -> Result<(), String> {
let pty = state.pty_sessions.write().await.remove(&pid).unwrap(); let pty = state.pty_sessions.write().await.remove(&pid).unwrap();
pty.kill_child().await.map_err(|e|e.to_string())?;
println!("RIP {pid:?}"); println!("RIP {pid:?}");
Ok(()) Ok(())