diff --git a/lib/src/action.rs b/lib/src/action.rs index aab60b9..8645f7b 100644 --- a/lib/src/action.rs +++ b/lib/src/action.rs @@ -12,8 +12,6 @@ use tokio::{ }; use tracing::{debug, trace, warn}; -pub use command_group::Signal; - use crate::{ command::Supervisor, error::{CriticalError, RuntimeError}, @@ -232,8 +230,16 @@ async fn apply_outcome( } (Some(p), Outcome::Signal(sig)) => { - // TODO: windows - p.signal(sig).await; + #[cfg(unix)] + if let Some(sig) = sig.to_nix() { + p.signal(sig).await; + } + + #[cfg(windows)] + if let SubSignal::Terminate = sig { + p.kill().await; + } + // else: https://github.com/watchexec/watchexec/issues/219 } (Some(p), Outcome::Wait) => { diff --git a/lib/src/action/outcome.rs b/lib/src/action/outcome.rs index 583b29f..99f72c6 100644 --- a/lib/src/action/outcome.rs +++ b/lib/src/action/outcome.rs @@ -1,4 +1,4 @@ -use command_group::Signal; +use crate::signal::process::SubSignal; #[derive(Clone, Debug, PartialEq, Eq)] #[non_exhaustive] @@ -16,7 +16,7 @@ pub enum Outcome { Wait, /// Send this signal to the command. - Signal(Signal), + Signal(SubSignal), /// Clear the (terminal) screen. Clear, diff --git a/lib/src/signal.rs b/lib/src/signal.rs index 78f4d61..c9f4d91 100644 --- a/lib/src/signal.rs +++ b/lib/src/signal.rs @@ -1,4 +1,4 @@ //! Signal handling. -pub mod source; pub mod process; +pub mod source; diff --git a/lib/src/signal/process.rs b/lib/src/signal/process.rs index 70ebf4a..d1529f9 100644 --- a/lib/src/signal/process.rs +++ b/lib/src/signal/process.rs @@ -95,24 +95,24 @@ pub enum SubSignal { impl SubSignal { #[cfg(unix)] - pub fn to_nix(self) -> Option { + pub fn to_nix(self) -> Option { use std::convert::TryFrom; - match self { - Self::Hangup => Some(NixSignal::SIGHUP), - Self::ForceStop => Some(NixSignal::SIGKILL), - Self::Interrupt => Some(NixSignal::SIGINT), - Self::Quit => Some(NixSignal::SIGQUIT), - Self::Terminate => Some(NixSignal::SIGTERM), - Self::User1 => Some(NixSignal::SIGUSR1), - Self::User2 => Some(NixSignal::SIGUSR2), - Self::Custom(sig) => NixSignal::try_from(sig).ok(), - } - } + match self { + Self::Hangup => Some(NixSignal::SIGHUP), + Self::ForceStop => Some(NixSignal::SIGKILL), + Self::Interrupt => Some(NixSignal::SIGINT), + Self::Quit => Some(NixSignal::SIGQUIT), + Self::Terminate => Some(NixSignal::SIGTERM), + Self::User1 => Some(NixSignal::SIGUSR1), + Self::User2 => Some(NixSignal::SIGUSR2), + Self::Custom(sig) => NixSignal::try_from(sig).ok(), + } + } #[cfg(unix)] pub fn from_nix(sig: NixSignal) -> Self { - match sig { + match sig { NixSignal::SIGHUP => Self::Hangup, NixSignal::SIGKILL => Self::ForceStop, NixSignal::SIGINT => Self::Interrupt, @@ -126,24 +126,24 @@ impl SubSignal { } impl From for SubSignal { - fn from(main: MainSignal) -> Self { - match main { - MainSignal::Hangup => Self::Hangup, - MainSignal::Interrupt => Self::Interrupt, - MainSignal::Quit => Self::Quit, - MainSignal::Terminate => Self::Terminate, - MainSignal::User1 => Self::User1, - MainSignal::User2 => Self::User2, - } - } + fn from(main: MainSignal) -> Self { + match main { + MainSignal::Hangup => Self::Hangup, + MainSignal::Interrupt => Self::Interrupt, + MainSignal::Quit => Self::Quit, + MainSignal::Terminate => Self::Terminate, + MainSignal::User1 => Self::User1, + MainSignal::User2 => Self::User2, + } + } } impl FromStr for SubSignal { - type Err = ParseSignalError; + type Err = ParseSignalError; #[cfg(unix)] - fn from_str(s: &str) -> Result { - use std::convert::TryFrom; + fn from_str(s: &str) -> Result { + use std::convert::TryFrom; if let Ok(sig) = i32::from_str(s) { if let Ok(sig) = NixSignal::try_from(sig) { @@ -151,23 +151,25 @@ impl FromStr for SubSignal { } } - if let Ok(sig) = NixSignal::from_str(&s.to_ascii_uppercase()).or_else(|_| NixSignal::from_str(&format!("SIG{}", s.to_ascii_uppercase()))) { + if let Ok(sig) = NixSignal::from_str(&s.to_ascii_uppercase()) + .or_else(|_| NixSignal::from_str(&format!("SIG{}", s.to_ascii_uppercase()))) + { return Ok(Self::from_nix(sig)); } Err(ParseSignalError::new(s, "unsupported signal")) - } + } #[cfg(windows)] fn from_str(s: &str) -> Result { - match s.to_ascii_uppercase().as_str() { + match s.to_ascii_uppercase().as_str() { "CTRL-CLOSE" | "CTRL+CLOSE" | "CLOSE" => Ok(Self::Hangup), "CTRL-BREAK" | "CTRL+BREAK" | "BREAK" => Ok(Self::Terminate), "CTRL-C" | "CTRL+C" | "C" => Ok(Self::Interrupt), "KILL" | "SIGKILL" | "FORCE-STOP" | "STOP" => Ok(Self::ForceStop), _ => Err(ParseSignalError::new(s, "unknown control name")), } - } + } #[cfg(not(any(unix, windows)))] fn from_str(s: &str) -> Result { @@ -181,8 +183,8 @@ impl FromStr for SubSignal { #[diagnostic(code(watchexec::signal::process::parse), url(docsrs))] pub struct ParseSignalError { // The string that was parsed. - #[source_code] - src: String, + #[source_code] + src: String, // The error that occurred. err: String,