Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make String to signal conversion more simplify by using a Trait. #122

Merged
merged 2 commits into from
Jul 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions src/delete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@ use std::path::PathBuf;

use anyhow::{bail, Result};
use clap::Clap;
use nix::sys::signal::Signal;

use crate::cgroups;
use crate::container::{Container, ContainerStatus};
use crate::utils;
use crate::{
container::{Container, ContainerStatus},
signal,
};
use nix::sys::signal as nix_signal;

#[derive(Clap, Debug)]
Expand All @@ -35,7 +33,7 @@ impl Delete {
log::debug!("load the container from {:?}", container_root);
let mut container = Container::load(container_root)?.refresh_status()?;
if container.can_kill() && self.force {
let sig = signal::from_str("SIGKILL")?;
let sig = Signal::SIGKILL;
log::debug!("kill signal {} to {}", sig, container.pid().unwrap());
nix_signal::kill(container.pid().unwrap(), sig)?;
container = container.update_status(ContainerStatus::Stopped);
Expand Down
4 changes: 2 additions & 2 deletions src/kill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use nix::sys::signal as nix_signal;

use crate::{
container::{Container, ContainerStatus},
signal,
signal::ToSignal,
};

#[derive(Clap, Debug)]
Expand All @@ -30,7 +30,7 @@ impl Kill {
// it might be possible that kill is invoked on a already stopped container etc.
let container = Container::load(container_root)?.refresh_status()?;
if container.can_kill() {
let sig = signal::from_str(self.signal.as_str())?;
let sig = self.signal.to_signal()?;
log::debug!("kill signal {} to {}", sig, container.pid().unwrap());
nix_signal::kill(container.pid().unwrap(), sig)?;
container.update_status(ContainerStatus::Stopped).save()?;
Expand Down
131 changes: 95 additions & 36 deletions src/signal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,99 @@
use anyhow::{bail, Result};
use nix::sys::signal::Signal;

pub fn from_str(signal: &str) -> Result<Signal> {
use Signal::*;
Ok(match signal.to_ascii_uppercase().as_str() {
"1" | "HUP" | "SIGHUP" => Signal::SIGHUP,
"2" | "INT" | "SIGINT" => Signal::SIGINT,
"3" | "QUIT" | "SIGQUIT" => Signal::SIGQUIT,
"4" | "ILL" | "SIGILL" => Signal::SIGILL,
"5" | "BUS" | "SIGBUS" => Signal::SIGBUS,
"6" | "ABRT" | "IOT" | "SIGABRT" | "SIGIOT" => Signal::SIGABRT,
"7" | "TRAP" | "SIGTRAP" => Signal::SIGTRAP,
"8" | "FPE" | "SIGFPE" => Signal::SIGFPE,
"9" | "KILL" | "SIGKILL" => Signal::SIGKILL,
"10" | "USR1" | "SIGUSR1" => Signal::SIGUSR1,
"11" | "SEGV" | "SIGSEGV" => SIGSEGV,
"12" | "USR2" | "SIGUSR2" => SIGUSR2,
"13" | "PIPE" | "SIGPIPE" => SIGPIPE,
"14" | "ALRM" | "SIGALRM" => SIGALRM,
"15" | "TERM" | "SIGTERM" => SIGTERM,
"16" | "STKFLT" | "SIGSTKFLT" => SIGSTKFLT,
"17" | "CHLD" | "SIGCHLD" => SIGCHLD,
"18" | "CONT" | "SIGCONT" => SIGCONT,
"19" | "STOP" | "SIGSTOP" => SIGSTOP,
"20" | "TSTP" | "SIGTSTP" => SIGTSTP,
"21" | "TTIN" | "SIGTTIN" => SIGTTIN,
"22" | "TTOU" | "SIGTTOU" => SIGTTOU,
"23" | "URG" | "SIGURG" => SIGURG,
"24" | "XCPU" | "SIGXCPU" => SIGXCPU,
"25" | "XFSZ" | "SIGXFSZ" => SIGXFSZ,
"26" | "VTALRM" | "SIGVTALRM" => SIGVTALRM,
"27" | "PROF" | "SIGPROF" => SIGPROF,
"28" | "WINCH" | "SIGWINCH" => SIGWINCH,
"29" | "IO" | "SIGIO" => SIGIO,
"30" | "PWR" | "SIGPWR" => SIGPWR,
"31" | "SYS" | "SIGSYS" => SIGSYS,
_ => bail! {"{} is not a valid signal", signal},
})
pub trait ToSignal<From = Self> {
Furisto marked this conversation as resolved.
Show resolved Hide resolved
fn to_signal(&self) -> Result<Signal>;
}

impl ToSignal for String {
fn to_signal(&self) -> Result<Signal> {
use Signal::*;
Ok(match self.to_ascii_uppercase().as_str() {
"1" | "HUP" | "SIGHUP" => SIGHUP,
"2" | "INT" | "SIGINT" => SIGINT,
"3" | "QUIT" | "SIGQUIT" => SIGQUIT,
"4" | "ILL" | "SIGILL" => SIGILL,
"5" | "BUS" | "SIGBUS" => SIGBUS,
"6" | "ABRT" | "IOT" | "SIGABRT" | "SIGIOT" => SIGABRT,
"7" | "TRAP" | "SIGTRAP" => SIGTRAP,
"8" | "FPE" | "SIGFPE" => SIGFPE,
"9" | "KILL" | "SIGKILL" => SIGKILL,
"10" | "USR1" | "SIGUSR1" => SIGUSR1,
"11" | "SEGV" | "SIGSEGV" => SIGSEGV,
"12" | "USR2" | "SIGUSR2" => SIGUSR2,
"13" | "PIPE" | "SIGPIPE" => SIGPIPE,
"14" | "ALRM" | "SIGALRM" => SIGALRM,
"15" | "TERM" | "SIGTERM" => SIGTERM,
"16" | "STKFLT" | "SIGSTKFLT" => SIGSTKFLT,
"17" | "CHLD" | "SIGCHLD" => SIGCHLD,
"18" | "CONT" | "SIGCONT" => SIGCONT,
"19" | "STOP" | "SIGSTOP" => SIGSTOP,
"20" | "TSTP" | "SIGTSTP" => SIGTSTP,
"21" | "TTIN" | "SIGTTIN" => SIGTTIN,
"22" | "TTOU" | "SIGTTOU" => SIGTTOU,
"23" | "URG" | "SIGURG" => SIGURG,
"24" | "XCPU" | "SIGXCPU" => SIGXCPU,
"25" | "XFSZ" | "SIGXFSZ" => SIGXFSZ,
"26" | "VTALRM" | "SIGVTALRM" => SIGVTALRM,
"27" | "PROF" | "SIGPROF" => SIGPROF,
"28" | "WINCH" | "SIGWINCH" => SIGWINCH,
"29" | "IO" | "SIGIO" => SIGIO,
"30" | "PWR" | "SIGPWR" => SIGPWR,
"31" | "SYS" | "SIGSYS" => SIGSYS,
_ => bail! {"{} is not a valid signal", self},
})
}
}

#[cfg(test)]
mod tests {
use super::*;
use nix::sys::signal::Signal::*;
use std::collections::HashMap;

#[test]
fn test_conversion_from_string() {
let mut test_sets = HashMap::new();
test_sets.insert(SIGHUP, vec!["1", "HUP", "SIGHUP"]);
test_sets.insert(SIGINT, vec!["2", "INT", "SIGINT"]);
test_sets.insert(SIGQUIT, vec!["3", "QUIT", "SIGQUIT"]);
test_sets.insert(SIGILL, vec!["4", "ILL", "SIGILL"]);
test_sets.insert(SIGBUS, vec!["5", "BUS", "SIGBUS"]);
test_sets.insert(SIGABRT, vec!["6", "ABRT", "IOT", "SIGABRT", "SIGIOT"]);
test_sets.insert(SIGTRAP, vec!["7", "TRAP", "SIGTRAP"]);
test_sets.insert(SIGFPE, vec!["8", "FPE", "SIGFPE"]);
test_sets.insert(SIGKILL, vec!["9", "KILL", "SIGKILL"]);
test_sets.insert(SIGUSR1, vec!["10", "USR1", "SIGUSR1"]);
test_sets.insert(SIGSEGV, vec!["11", "SEGV", "SIGSEGV"]);
test_sets.insert(SIGUSR2, vec!["12", "USR2", "SIGUSR2"]);
test_sets.insert(SIGPIPE, vec!["13", "PIPE", "SIGPIPE"]);
test_sets.insert(SIGALRM, vec!["14", "ALRM", "SIGALRM"]);
test_sets.insert(SIGTERM, vec!["15", "TERM", "SIGTERM"]);
test_sets.insert(SIGSTKFLT, vec!["16", "STKFLT", "SIGSTKFLT"]);
test_sets.insert(SIGCHLD, vec!["17", "CHLD", "SIGCHLD"]);
test_sets.insert(SIGCONT, vec!["18", "CONT", "SIGCONT"]);
test_sets.insert(SIGSTOP, vec!["19", "STOP", "SIGSTOP"]);
test_sets.insert(SIGTSTP, vec!["20", "TSTP", "SIGTSTP"]);
test_sets.insert(SIGTTIN, vec!["21", "TTIN", "SIGTTIN"]);
test_sets.insert(SIGTTOU, vec!["22", "TTOU", "SIGTTOU"]);
test_sets.insert(SIGURG, vec!["23", "URG", "SIGURG"]);
test_sets.insert(SIGXCPU, vec!["24", "XCPU", "SIGXCPU"]);
test_sets.insert(SIGXFSZ, vec!["25", "XFSZ", "SIGXFSZ"]);
test_sets.insert(SIGVTALRM, vec!["26", "VTALRM", "SIGVTALRM"]);
test_sets.insert(SIGPROF, vec!["27", "PROF", "SIGPROF"]);
test_sets.insert(SIGWINCH, vec!["28", "WINCH", "SIGWINCH"]);
test_sets.insert(SIGIO, vec!["29", "IO", "SIGIO"]);
test_sets.insert(SIGPWR, vec!["30", "PWR", "SIGPWR"]);
test_sets.insert(SIGSYS, vec!["31", "SYS", "SIGSYS"]);
for (signal, strings) in test_sets {
for s in strings {
assert_eq!(signal, s.to_string().to_signal().unwrap());
}
}
}

#[test]
fn test_conversion_from_string_should_be_failed() {
assert!("invalid".to_string().to_signal().is_err())
}
}