1use crate::Signal;
4
5#[cfg(any(
6 target_os = "dragonfly",
7 target_os = "freebsd",
8 target_os = "ios",
9 target_os = "macos",
10 target_os = "netbsd",
11 target_os = "openbsd"
12))]
13mod kqueue;
14
15#[cfg(any(
16 target_os = "dragonfly",
17 target_os = "freebsd",
18 target_os = "ios",
19 target_os = "macos",
20 target_os = "netbsd",
21 target_os = "openbsd"
22))]
23pub use self::kqueue::Signals;
24
25#[cfg(any(target_os = "linux", target_os = "android"))]
26mod signalfd;
27
28#[cfg(any(target_os = "linux", target_os = "android"))]
29pub use self::signalfd::Signals;
30
31#[cfg(unix)]
32pub fn send_signal(pid: u32, signal: Signal) -> std::io::Result<()> {
33 if unsafe { libc::kill(pid as libc::pid_t, raw_signal(signal)) } != 0 {
34 Err(std::io::Error::last_os_error())
35 } else {
36 Ok(())
37 }
38}
39
40fn raw_signal(signal: Signal) -> libc::c_int {
44 match signal {
45 Signal::Interrupt => libc::SIGINT,
46 Signal::Quit => libc::SIGQUIT,
47 Signal::Terminate => libc::SIGTERM,
48 Signal::User1 => libc::SIGUSR1,
49 Signal::User2 => libc::SIGUSR2,
50 }
51}
52
53fn from_raw_signal(raw_signal: libc::c_int) -> Option<Signal> {
55 match raw_signal {
56 libc::SIGINT => Some(Signal::Interrupt),
57 libc::SIGQUIT => Some(Signal::Quit),
58 libc::SIGTERM => Some(Signal::Terminate),
59 libc::SIGUSR1 => Some(Signal::User1),
60 libc::SIGUSR2 => Some(Signal::User2),
61 _ => None,
62 }
63}
64
65#[test]
66fn test_from_raw_signal() {
67 assert_eq!(from_raw_signal(libc::SIGINT), Some(Signal::Interrupt));
68 assert_eq!(from_raw_signal(libc::SIGQUIT), Some(Signal::Quit));
69 assert_eq!(from_raw_signal(libc::SIGTERM), Some(Signal::Terminate));
70 assert_eq!(from_raw_signal(libc::SIGUSR1), Some(Signal::User1));
71 assert_eq!(from_raw_signal(libc::SIGUSR2), Some(Signal::User2));
72
73 assert_eq!(from_raw_signal(libc::SIGSTOP), None);
75}
76
77#[test]
78fn test_raw_signal() {
79 assert_eq!(raw_signal(Signal::Interrupt), libc::SIGINT);
80 assert_eq!(raw_signal(Signal::Quit), libc::SIGQUIT);
81 assert_eq!(raw_signal(Signal::Terminate), libc::SIGTERM);
82 assert_eq!(raw_signal(Signal::User1), libc::SIGUSR1);
83 assert_eq!(raw_signal(Signal::User2), libc::SIGUSR2);
84}
85
86#[test]
87fn raw_signal_round_trip() {
88 assert_eq!(
89 raw_signal(from_raw_signal(libc::SIGINT).unwrap()),
90 libc::SIGINT
91 );
92 assert_eq!(
93 raw_signal(from_raw_signal(libc::SIGQUIT).unwrap()),
94 libc::SIGQUIT
95 );
96 assert_eq!(
97 raw_signal(from_raw_signal(libc::SIGTERM).unwrap()),
98 libc::SIGTERM
99 );
100 assert_eq!(
101 raw_signal(from_raw_signal(libc::SIGUSR1).unwrap()),
102 libc::SIGUSR1
103 );
104 assert_eq!(
105 raw_signal(from_raw_signal(libc::SIGUSR2).unwrap()),
106 libc::SIGUSR2
107 );
108}