summaryrefslogtreecommitdiff
path: root/src/sys/signal.rs
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2018-09-05 15:19:00 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2018-09-05 15:19:00 +0000
commitd302e8d278bcd5b10ab7a30a467b5d8e21139ff2 (patch)
treee50cca8662bbaf5007d807139fba6732dcc709b7 /src/sys/signal.rs
parent11dad1672b8a70a140d2329b2732abe19334a054 (diff)
parent8de86cc86f19db3a9097cffb9a7b458716623fe3 (diff)
downloadnix-d302e8d278bcd5b10ab7a30a467b5d8e21139ff2.zip
Merge #884
884: impl FromStr for sys::Signal r=Susurrus a=quodlibetor This implements both ALLCAPS and lowercase full name (including SIG) and short name. This matches what `kill` accepts in many shells, and it also allows the `Debug` representation of `Signal`, which means it can be round-tripped, if desired. Co-authored-by: Brandon W Maister <quodlibetor@gmail.com>
Diffstat (limited to 'src/sys/signal.rs')
-rw-r--r--src/sys/signal.rs116
1 files changed, 116 insertions, 0 deletions
diff --git a/src/sys/signal.rs b/src/sys/signal.rs
index 73c3a958..c2dd856c 100644
--- a/src/sys/signal.rs
+++ b/src/sys/signal.rs
@@ -7,6 +7,8 @@ use libc;
use {Error, Result};
use errno::Errno;
use std::mem;
+use std::fmt;
+use std::str::FromStr;
#[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
use std::os::unix::io::RawFd;
use std::ptr;
@@ -62,6 +64,104 @@ libc_enum!{
}
}
+impl FromStr for Signal {
+ type Err = Error;
+ fn from_str(s: &str) -> Result<Signal> {
+ Ok(match s {
+ "SIGHUP" => Signal::SIGHUP,
+ "SIGINT" => Signal::SIGINT,
+ "SIGQUIT" => Signal::SIGQUIT,
+ "SIGILL" => Signal::SIGILL,
+ "SIGTRAP" => Signal::SIGTRAP,
+ "SIGABRT" => Signal::SIGABRT,
+ "SIGBUS" => Signal::SIGBUS,
+ "SIGFPE" => Signal::SIGFPE,
+ "SIGKILL" => Signal::SIGKILL,
+ "SIGUSR1" => Signal::SIGUSR1,
+ "SIGSEGV" => Signal::SIGSEGV,
+ "SIGUSR2" => Signal::SIGUSR2,
+ "SIGPIPE" => Signal::SIGPIPE,
+ "SIGALRM" => Signal::SIGALRM,
+ "SIGTERM" => Signal::SIGTERM,
+ #[cfg(all(any(target_os = "android", target_os = "emscripten", target_os = "linux"),
+ not(any(target_arch = "mips", target_arch = "mips64"))))]
+ "SIGSTKFLT" => Signal::SIGSTKFLT,
+ "SIGCHLD" => Signal::SIGCHLD,
+ "SIGCONT" => Signal::SIGCONT,
+ "SIGSTOP" => Signal::SIGSTOP,
+ "SIGTSTP" => Signal::SIGTSTP,
+ "SIGTTIN" => Signal::SIGTTIN,
+ "SIGTTOU" => Signal::SIGTTOU,
+ "SIGURG" => Signal::SIGURG,
+ "SIGXCPU" => Signal::SIGXCPU,
+ "SIGXFSZ" => Signal::SIGXFSZ,
+ "SIGVTALRM" => Signal::SIGVTALRM,
+ "SIGPROF" => Signal::SIGPROF,
+ "SIGWINCH" => Signal::SIGWINCH,
+ "SIGIO" => Signal::SIGIO,
+ #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "linux"))]
+ "SIGPWR" => Signal::SIGPWR,
+ "SIGSYS" => Signal::SIGSYS,
+ #[cfg(not(any(target_os = "android", target_os = "emscripten", target_os = "linux")))]
+ "SIGEMT" => Signal::SIGEMT,
+ #[cfg(not(any(target_os = "android", target_os = "emscripten", target_os = "linux")))]
+ "SIGINFO" => Signal::SIGINFO,
+ _ => return Err(Error::invalid_argument()),
+ })
+ }
+}
+
+impl AsRef<str> for Signal {
+ fn as_ref(&self) -> &str {
+ match *self {
+ Signal::SIGHUP => "SIGHUP",
+ Signal::SIGINT => "SIGINT",
+ Signal::SIGQUIT => "SIGQUIT",
+ Signal::SIGILL => "SIGILL",
+ Signal::SIGTRAP => "SIGTRAP",
+ Signal::SIGABRT => "SIGABRT",
+ Signal::SIGBUS => "SIGBUS",
+ Signal::SIGFPE => "SIGFPE",
+ Signal::SIGKILL => "SIGKILL",
+ Signal::SIGUSR1 => "SIGUSR1",
+ Signal::SIGSEGV => "SIGSEGV",
+ Signal::SIGUSR2 => "SIGUSR2",
+ Signal::SIGPIPE => "SIGPIPE",
+ Signal::SIGALRM => "SIGALRM",
+ Signal::SIGTERM => "SIGTERM",
+ #[cfg(all(any(target_os = "android", target_os = "emscripten", target_os = "linux"),
+ not(any(target_arch = "mips", target_arch = "mips64"))))]
+ Signal::SIGSTKFLT => "SIGSTKFLT",
+ Signal::SIGCHLD => "SIGCHLD",
+ Signal::SIGCONT => "SIGCONT",
+ Signal::SIGSTOP => "SIGSTOP",
+ Signal::SIGTSTP => "SIGTSTP",
+ Signal::SIGTTIN => "SIGTTIN",
+ Signal::SIGTTOU => "SIGTTOU",
+ Signal::SIGURG => "SIGURG",
+ Signal::SIGXCPU => "SIGXCPU",
+ Signal::SIGXFSZ => "SIGXFSZ",
+ Signal::SIGVTALRM => "SIGVTALRM",
+ Signal::SIGPROF => "SIGPROF",
+ Signal::SIGWINCH => "SIGWINCH",
+ Signal::SIGIO => "SIGIO",
+ #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "linux"))]
+ Signal::SIGPWR => "SIGPWR",
+ Signal::SIGSYS => "SIGSYS",
+ #[cfg(not(any(target_os = "android", target_os = "emscripten", target_os = "linux")))]
+ Signal::SIGEMT => "SIGEMT",
+ #[cfg(not(any(target_os = "android", target_os = "emscripten", target_os = "linux")))]
+ Signal::SIGINFO => "SIGINFO",
+ }
+ }
+}
+
+impl fmt::Display for Signal {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str(self.as_ref())
+ }
+}
+
pub use self::Signal::*;
#[cfg(all(any(target_os = "linux", target_os = "android", target_os = "emscripten"), not(any(target_arch = "mips", target_arch = "mips64"))))]
@@ -685,6 +785,22 @@ mod tests {
}
#[test]
+ fn test_from_str_round_trips() {
+ for signal in Signal::iterator() {
+ assert_eq!(signal.as_ref().parse::<Signal>().unwrap(), signal);
+ assert_eq!(signal.to_string().parse::<Signal>().unwrap(), signal);
+ }
+ }
+
+ #[test]
+ fn test_from_str_invalid_value() {
+ let errval = Err(Error::Sys(Errno::EINVAL));
+ assert_eq!("NOSIGNAL".parse::<Signal>(), errval);
+ assert_eq!("kill".parse::<Signal>(), errval);
+ assert_eq!("9".parse::<Signal>(), errval);
+ }
+
+ #[test]
fn test_extend() {
let mut one_signal = SigSet::empty();
one_signal.add(SIGUSR1);