diff options
Diffstat (limited to 'src/platform/mod.rs')
| -rw-r--r-- | src/platform/mod.rs | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/src/platform/mod.rs b/src/platform/mod.rs index 86a431aa..d48ad4fa 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -25,6 +25,36 @@ pub enum Signal { Kill, } +/// Why a pane runtime ended, before application persistence policy is applied. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum ChildExitReason { + Exited, + Interrupted, + /// Imported runtimes have no child wait handle in the replacement server. + #[cfg(unix)] + Handoff, + WaitFailed, +} + +impl ChildExitReason { + pub(crate) fn requires_session_checkpoint(self) -> bool { + match self { + Self::Interrupted => true, + #[cfg(unix)] + Self::Handoff => true, + _ => false, + } + } +} + +#[cfg(unix)] +pub(crate) use unix_common::classify_child_exit; + +#[cfg(not(any(unix, windows)))] +pub(crate) fn classify_child_exit(_status: &portable_pty::ExitStatus) -> ChildExitReason { + ChildExitReason::Exited +} + pub(crate) fn detached_custom_command_process(command: &str) -> std::process::Command { let mut process = detached_custom_command_process_platform(command); configure_background_command(&mut process); @@ -415,6 +445,25 @@ impl PrefixInputSource for RealPrefixInputSource { } } +#[cfg(all(test, any(unix, windows)))] +#[test] +fn child_exit_classification_only_checkpoints_interruptions() { + for code in [0, 1, 130, 255, 0xC0000005] { + let reason = classify_child_exit(&portable_pty::ExitStatus::with_exit_code(code)); + assert_eq!(reason, ChildExitReason::Exited, "exit code {code:#x}"); + assert!(!reason.requires_session_checkpoint()); + } + #[cfg(windows)] + let status = portable_pty::ExitStatus::with_exit_code(0xC000013A); + #[cfg(not(windows))] + let status = portable_pty::ExitStatus::with_signal("Terminated: 15"); + assert_eq!(classify_child_exit(&status), ChildExitReason::Interrupted); + assert!(classify_child_exit(&status).requires_session_checkpoint()); + #[cfg(unix)] + assert!(ChildExitReason::Handoff.requires_session_checkpoint()); + assert!(!ChildExitReason::WaitFailed.requires_session_checkpoint()); +} + #[cfg(all(test, unix))] mod tests { use super::*; |
