diff options
| author | Can Celik <ogulcancelik@gmail.com> | 2026-09-07 16:14:46 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-09-07 15:14:46 +0200 |
| commit | e7d8220788b4fa7c266a1e4457591b694478771c (patch) | |
| tree | 272303d74e0b58c11f9c0c434dae8335d3d06703 /src/pane.rs | |
| parent | 482818130407691154d1635d4029b95d0e730104 (diff) | |
fix: preserve sessions after interrupted pane exits (#3418)
* fix: preserve sessions when pane shells are signaled
refs #3415
* fix: preserve shutdown checkpoints across platforms
refs #3415
---------
Co-authored-by: Jonathan Liebig <jonathan.liebig@gmail.com>
Diffstat (limited to 'src/pane.rs')
| -rw-r--r-- | src/pane.rs | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/src/pane.rs b/src/pane.rs index 83bad900..aa6acb57 100644 --- a/src/pane.rs +++ b/src/pane.rs @@ -2194,7 +2194,12 @@ impl PaneRuntime { }); let exit_events = events.clone(); let on_reader_exit = Box::new(move || { - let _ = rt.block_on(exit_events.send(AppEvent::PaneDied { pane_id })); + // Imported handoff panes have no child wait handle, so their exit cause is + // unknowable. Checkpoint conservatively; normal autosave settles clean exits. + let _ = rt.block_on(exit_events.send(AppEvent::PaneDied { + pane_id, + exit_reason: crate::platform::ChildExitReason::Handoff, + })); debug!(pane = pane_id.raw(), "handoff PTY actor exiting"); }); PaneRuntimeIo::Actor(PtyIoActor::spawn(PtyIoActorConfig { @@ -2299,16 +2304,24 @@ impl PaneRuntime { crate::logging::pane_spawned(pane_id.raw(), pid); } tokio::task::spawn_blocking(move || { - match child.wait() { + let exit_reason = match child.wait() { Ok(status) => { + let exit_reason = crate::platform::classify_child_exit(&status); let status_text = format!("{status:?}"); crate::logging::pane_exited(pane_id.raw(), &status_text); + exit_reason } - Err(e) => crate::logging::pane_exit_failed(pane_id.raw(), &e.to_string()), - } + Err(e) => { + crate::logging::pane_exit_failed(pane_id.raw(), &e.to_string()); + crate::platform::ChildExitReason::WaitFailed + } + }; child_wait_completed.store(true, Ordering::Release); // Use blocking send — PaneDied is critical, must not be dropped - if let Err(e) = rt.block_on(events.send(AppEvent::PaneDied { pane_id })) { + if let Err(e) = rt.block_on(events.send(AppEvent::PaneDied { + pane_id, + exit_reason, + })) { error!(pane = pane_id.raw(), err = %e, "failed to send PaneDied event"); } }); |
