Skip to content

Commit

Permalink
Merge pull request #122 from utam0k/refactor-signal
Browse files Browse the repository at this point in the history
make String to signal conversion more simplify by using a Trait.
  • Loading branch information
utam0k authored Jul 6, 2021
2 parents c22f73e + 6e5eee0 commit 0b8d378
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 43 deletions.
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> {
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())
}
}

0 comments on commit 0b8d378

Please # to comment.