mirror of
https://github.com/watchexec/watchexec.git
synced 2024-09-28 14:11:34 +02:00
Handle signalling to sub process on non-unix
This commit is contained in:
parent
92513a4dc3
commit
e577b040b9
@ -12,8 +12,6 @@ use tokio::{
|
|||||||
};
|
};
|
||||||
use tracing::{debug, trace, warn};
|
use tracing::{debug, trace, warn};
|
||||||
|
|
||||||
pub use command_group::Signal;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
command::Supervisor,
|
command::Supervisor,
|
||||||
error::{CriticalError, RuntimeError},
|
error::{CriticalError, RuntimeError},
|
||||||
@ -232,8 +230,16 @@ async fn apply_outcome(
|
|||||||
}
|
}
|
||||||
|
|
||||||
(Some(p), Outcome::Signal(sig)) => {
|
(Some(p), Outcome::Signal(sig)) => {
|
||||||
// TODO: windows
|
#[cfg(unix)]
|
||||||
p.signal(sig).await;
|
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) => {
|
(Some(p), Outcome::Wait) => {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use command_group::Signal;
|
use crate::signal::process::SubSignal;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
@ -16,7 +16,7 @@ pub enum Outcome {
|
|||||||
Wait,
|
Wait,
|
||||||
|
|
||||||
/// Send this signal to the command.
|
/// Send this signal to the command.
|
||||||
Signal(Signal),
|
Signal(SubSignal),
|
||||||
|
|
||||||
/// Clear the (terminal) screen.
|
/// Clear the (terminal) screen.
|
||||||
Clear,
|
Clear,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//! Signal handling.
|
//! Signal handling.
|
||||||
|
|
||||||
pub mod source;
|
|
||||||
pub mod process;
|
pub mod process;
|
||||||
|
pub mod source;
|
||||||
|
@ -95,24 +95,24 @@ pub enum SubSignal {
|
|||||||
|
|
||||||
impl SubSignal {
|
impl SubSignal {
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
pub fn to_nix(self) -> Option<NixSignal> {
|
pub fn to_nix(self) -> Option<NixSignal> {
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Self::Hangup => Some(NixSignal::SIGHUP),
|
Self::Hangup => Some(NixSignal::SIGHUP),
|
||||||
Self::ForceStop => Some(NixSignal::SIGKILL),
|
Self::ForceStop => Some(NixSignal::SIGKILL),
|
||||||
Self::Interrupt => Some(NixSignal::SIGINT),
|
Self::Interrupt => Some(NixSignal::SIGINT),
|
||||||
Self::Quit => Some(NixSignal::SIGQUIT),
|
Self::Quit => Some(NixSignal::SIGQUIT),
|
||||||
Self::Terminate => Some(NixSignal::SIGTERM),
|
Self::Terminate => Some(NixSignal::SIGTERM),
|
||||||
Self::User1 => Some(NixSignal::SIGUSR1),
|
Self::User1 => Some(NixSignal::SIGUSR1),
|
||||||
Self::User2 => Some(NixSignal::SIGUSR2),
|
Self::User2 => Some(NixSignal::SIGUSR2),
|
||||||
Self::Custom(sig) => NixSignal::try_from(sig).ok(),
|
Self::Custom(sig) => NixSignal::try_from(sig).ok(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
pub fn from_nix(sig: NixSignal) -> Self {
|
pub fn from_nix(sig: NixSignal) -> Self {
|
||||||
match sig {
|
match sig {
|
||||||
NixSignal::SIGHUP => Self::Hangup,
|
NixSignal::SIGHUP => Self::Hangup,
|
||||||
NixSignal::SIGKILL => Self::ForceStop,
|
NixSignal::SIGKILL => Self::ForceStop,
|
||||||
NixSignal::SIGINT => Self::Interrupt,
|
NixSignal::SIGINT => Self::Interrupt,
|
||||||
@ -126,24 +126,24 @@ impl SubSignal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<MainSignal> for SubSignal {
|
impl From<MainSignal> for SubSignal {
|
||||||
fn from(main: MainSignal) -> Self {
|
fn from(main: MainSignal) -> Self {
|
||||||
match main {
|
match main {
|
||||||
MainSignal::Hangup => Self::Hangup,
|
MainSignal::Hangup => Self::Hangup,
|
||||||
MainSignal::Interrupt => Self::Interrupt,
|
MainSignal::Interrupt => Self::Interrupt,
|
||||||
MainSignal::Quit => Self::Quit,
|
MainSignal::Quit => Self::Quit,
|
||||||
MainSignal::Terminate => Self::Terminate,
|
MainSignal::Terminate => Self::Terminate,
|
||||||
MainSignal::User1 => Self::User1,
|
MainSignal::User1 => Self::User1,
|
||||||
MainSignal::User2 => Self::User2,
|
MainSignal::User2 => Self::User2,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for SubSignal {
|
impl FromStr for SubSignal {
|
||||||
type Err = ParseSignalError;
|
type Err = ParseSignalError;
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
if let Ok(sig) = i32::from_str(s) {
|
if let Ok(sig) = i32::from_str(s) {
|
||||||
if let Ok(sig) = NixSignal::try_from(sig) {
|
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));
|
return Ok(Self::from_nix(sig));
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(ParseSignalError::new(s, "unsupported signal"))
|
Err(ParseSignalError::new(s, "unsupported signal"))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
match s.to_ascii_uppercase().as_str() {
|
match s.to_ascii_uppercase().as_str() {
|
||||||
"CTRL-CLOSE" | "CTRL+CLOSE" | "CLOSE" => Ok(Self::Hangup),
|
"CTRL-CLOSE" | "CTRL+CLOSE" | "CLOSE" => Ok(Self::Hangup),
|
||||||
"CTRL-BREAK" | "CTRL+BREAK" | "BREAK" => Ok(Self::Terminate),
|
"CTRL-BREAK" | "CTRL+BREAK" | "BREAK" => Ok(Self::Terminate),
|
||||||
"CTRL-C" | "CTRL+C" | "C" => Ok(Self::Interrupt),
|
"CTRL-C" | "CTRL+C" | "C" => Ok(Self::Interrupt),
|
||||||
"KILL" | "SIGKILL" | "FORCE-STOP" | "STOP" => Ok(Self::ForceStop),
|
"KILL" | "SIGKILL" | "FORCE-STOP" | "STOP" => Ok(Self::ForceStop),
|
||||||
_ => Err(ParseSignalError::new(s, "unknown control name")),
|
_ => Err(ParseSignalError::new(s, "unknown control name")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(unix, windows)))]
|
#[cfg(not(any(unix, windows)))]
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
@ -181,8 +183,8 @@ impl FromStr for SubSignal {
|
|||||||
#[diagnostic(code(watchexec::signal::process::parse), url(docsrs))]
|
#[diagnostic(code(watchexec::signal::process::parse), url(docsrs))]
|
||||||
pub struct ParseSignalError {
|
pub struct ParseSignalError {
|
||||||
// The string that was parsed.
|
// The string that was parsed.
|
||||||
#[source_code]
|
#[source_code]
|
||||||
src: String,
|
src: String,
|
||||||
|
|
||||||
// The error that occurred.
|
// The error that occurred.
|
||||||
err: String,
|
err: String,
|
||||||
|
Loading…
Reference in New Issue
Block a user