signal_child/
signal.rs

1//! Signals that can be sent to processes
2//!
3//! This signal module is mostly taken from the
4//! [nix](https://crates.io/crates/nix) crate.
5use std::str::FromStr;
6use std::{convert::TryFrom, fmt, mem};
7
8/// An enum of valid signal values
9///
10/// Please refer to
11/// [`signal.h(0p)`](https://man7.org/linux/man-pages/man0/signal.h.0p.html)
12/// or other relevant documentation for what each signal does.
13#[repr(i32)]
14#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
15pub enum Signal {
16    SIGHUP,
17    SIGINT,
18    SIGQUIT,
19    SIGILL,
20    SIGTRAP,
21    SIGABRT,
22    SIGBUS,
23    SIGFPE,
24    SIGKILL,
25    SIGUSR1,
26    SIGSEGV,
27    SIGUSR2,
28    SIGPIPE,
29    SIGALRM,
30    SIGTERM,
31    #[cfg(all(
32        any(
33            target_os = "android",
34            target_os = "emscripten",
35            target_os = "fuchsia",
36            target_os = "linux"
37        ),
38        not(any(
39            target_arch = "mips",
40            target_arch = "mips64",
41            target_arch = "sparc64"
42        ))
43    ))]
44    SIGSTKFLT,
45    SIGCHLD,
46    SIGCONT,
47    SIGSTOP,
48    SIGTSTP,
49    SIGTTIN,
50    SIGTTOU,
51    SIGURG,
52    SIGXCPU,
53    SIGXFSZ,
54    SIGVTALRM,
55    SIGPROF,
56    SIGWINCH,
57    SIGIO,
58    #[cfg(any(
59        target_os = "android",
60        target_os = "emscripten",
61        target_os = "fuchsia",
62        target_os = "linux"
63    ))]
64    SIGPWR,
65    SIGSYS,
66    #[cfg(not(any(
67        target_os = "android",
68        target_os = "emscripten",
69        target_os = "fuchsia",
70        target_os = "linux",
71        target_os = "redox"
72    )))]
73    SIGEMT,
74    #[cfg(not(any(
75        target_os = "android",
76        target_os = "emscripten",
77        target_os = "fuchsia",
78        target_os = "linux",
79        target_os = "redox"
80    )))]
81    SIGINFO,
82}
83
84impl FromStr for Signal {
85    type Err = InvalidSignal;
86    fn from_str(s: &str) -> Result<Signal, InvalidSignal> {
87        Ok(match s {
88            "SIGHUP" => Signal::SIGHUP,
89            "SIGINT" => Signal::SIGINT,
90            "SIGQUIT" => Signal::SIGQUIT,
91            "SIGILL" => Signal::SIGILL,
92            "SIGTRAP" => Signal::SIGTRAP,
93            "SIGABRT" => Signal::SIGABRT,
94            "SIGBUS" => Signal::SIGBUS,
95            "SIGFPE" => Signal::SIGFPE,
96            "SIGKILL" => Signal::SIGKILL,
97            "SIGUSR1" => Signal::SIGUSR1,
98            "SIGSEGV" => Signal::SIGSEGV,
99            "SIGUSR2" => Signal::SIGUSR2,
100            "SIGPIPE" => Signal::SIGPIPE,
101            "SIGALRM" => Signal::SIGALRM,
102            "SIGTERM" => Signal::SIGTERM,
103            #[cfg(all(
104                any(
105                    target_os = "android",
106                    target_os = "emscripten",
107                    target_os = "fuchsia",
108                    target_os = "linux"
109                ),
110                not(any(
111                    target_arch = "mips",
112                    target_arch = "mips64",
113                    target_arch = "sparc64"
114                ))
115            ))]
116            "SIGSTKFLT" => Signal::SIGSTKFLT,
117            "SIGCHLD" => Signal::SIGCHLD,
118            "SIGCONT" => Signal::SIGCONT,
119            "SIGSTOP" => Signal::SIGSTOP,
120            "SIGTSTP" => Signal::SIGTSTP,
121            "SIGTTIN" => Signal::SIGTTIN,
122            "SIGTTOU" => Signal::SIGTTOU,
123            "SIGURG" => Signal::SIGURG,
124            "SIGXCPU" => Signal::SIGXCPU,
125            "SIGXFSZ" => Signal::SIGXFSZ,
126            "SIGVTALRM" => Signal::SIGVTALRM,
127            "SIGPROF" => Signal::SIGPROF,
128            "SIGWINCH" => Signal::SIGWINCH,
129            "SIGIO" => Signal::SIGIO,
130            #[cfg(any(
131                target_os = "android",
132                target_os = "emscripten",
133                target_os = "fuchsia",
134                target_os = "linux"
135            ))]
136            "SIGPWR" => Signal::SIGPWR,
137            "SIGSYS" => Signal::SIGSYS,
138            #[cfg(not(any(
139                target_os = "android",
140                target_os = "emscripten",
141                target_os = "fuchsia",
142                target_os = "linux",
143                target_os = "redox"
144            )))]
145            "SIGEMT" => Signal::SIGEMT,
146            #[cfg(not(any(
147                target_os = "android",
148                target_os = "emscripten",
149                target_os = "fuchsia",
150                target_os = "linux",
151                target_os = "redox"
152            )))]
153            "SIGINFO" => Signal::SIGINFO,
154            _ => return Err(InvalidSignal),
155        })
156    }
157}
158
159impl Signal {
160    /// Returns name of signal.
161    ///
162    /// This function is equivalent to `<Signal as AsRef<str>>::as_ref()`,
163    /// with difference that returned string is `'static`
164    /// and not bound to `self`'s lifetime.
165    pub fn as_str(self) -> &'static str {
166        match self {
167            Signal::SIGHUP => "SIGHUP",
168            Signal::SIGINT => "SIGINT",
169            Signal::SIGQUIT => "SIGQUIT",
170            Signal::SIGILL => "SIGILL",
171            Signal::SIGTRAP => "SIGTRAP",
172            Signal::SIGABRT => "SIGABRT",
173            Signal::SIGBUS => "SIGBUS",
174            Signal::SIGFPE => "SIGFPE",
175            Signal::SIGKILL => "SIGKILL",
176            Signal::SIGUSR1 => "SIGUSR1",
177            Signal::SIGSEGV => "SIGSEGV",
178            Signal::SIGUSR2 => "SIGUSR2",
179            Signal::SIGPIPE => "SIGPIPE",
180            Signal::SIGALRM => "SIGALRM",
181            Signal::SIGTERM => "SIGTERM",
182            #[cfg(all(
183                any(
184                    target_os = "android",
185                    target_os = "emscripten",
186                    target_os = "fuchsia",
187                    target_os = "linux"
188                ),
189                not(any(
190                    target_arch = "mips",
191                    target_arch = "mips64",
192                    target_arch = "sparc64"
193                ))
194            ))]
195            Signal::SIGSTKFLT => "SIGSTKFLT",
196            Signal::SIGCHLD => "SIGCHLD",
197            Signal::SIGCONT => "SIGCONT",
198            Signal::SIGSTOP => "SIGSTOP",
199            Signal::SIGTSTP => "SIGTSTP",
200            Signal::SIGTTIN => "SIGTTIN",
201            Signal::SIGTTOU => "SIGTTOU",
202            Signal::SIGURG => "SIGURG",
203            Signal::SIGXCPU => "SIGXCPU",
204            Signal::SIGXFSZ => "SIGXFSZ",
205            Signal::SIGVTALRM => "SIGVTALRM",
206            Signal::SIGPROF => "SIGPROF",
207            Signal::SIGWINCH => "SIGWINCH",
208            Signal::SIGIO => "SIGIO",
209            #[cfg(any(
210                target_os = "android",
211                target_os = "emscripten",
212                target_os = "fuchsia",
213                target_os = "linux"
214            ))]
215            Signal::SIGPWR => "SIGPWR",
216            Signal::SIGSYS => "SIGSYS",
217            #[cfg(not(any(
218                target_os = "android",
219                target_os = "emscripten",
220                target_os = "fuchsia",
221                target_os = "linux",
222                target_os = "redox"
223            )))]
224            Signal::SIGEMT => "SIGEMT",
225            #[cfg(not(any(
226                target_os = "android",
227                target_os = "emscripten",
228                target_os = "fuchsia",
229                target_os = "linux",
230                target_os = "redox"
231            )))]
232            Signal::SIGINFO => "SIGINFO",
233        }
234    }
235}
236
237impl AsRef<str> for Signal {
238    fn as_ref(&self) -> &str {
239        self.as_str()
240    }
241}
242
243impl fmt::Display for Signal {
244    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
245        f.write_str(self.as_ref())
246    }
247}
248
249use crate::error::InvalidSignal;
250
251pub use self::Signal::*;
252
253#[cfg(target_os = "redox")]
254const SIGNALS: [Signal; 29] = [
255    SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGBUS, SIGFPE, SIGKILL,
256    SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGCONT,
257    SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, SIGXCPU, SIGXFSZ, SIGVTALRM,
258    SIGPROF, SIGWINCH, SIGIO, SIGSYS,
259];
260#[cfg(all(
261    any(
262        target_os = "linux",
263        target_os = "android",
264        target_os = "emscripten",
265        target_os = "fuchsia"
266    ),
267    not(any(
268        target_arch = "mips",
269        target_arch = "mips64",
270        target_arch = "sparc64"
271    ))
272))]
273const SIGNALS: [Signal; 31] = [
274    SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGBUS, SIGFPE, SIGKILL,
275    SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM, SIGTERM, SIGSTKFLT, SIGCHLD,
276    SIGCONT, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, SIGXCPU, SIGXFSZ,
277    SIGVTALRM, SIGPROF, SIGWINCH, SIGIO, SIGPWR, SIGSYS,
278];
279#[cfg(all(
280    any(
281        target_os = "linux",
282        target_os = "android",
283        target_os = "emscripten",
284        target_os = "fuchsia"
285    ),
286    any(target_arch = "mips", target_arch = "mips64", target_arch = "sparc64")
287))]
288const SIGNALS: [Signal; 30] = [
289    SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGBUS, SIGFPE, SIGKILL,
290    SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGCONT,
291    SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, SIGXCPU, SIGXFSZ, SIGVTALRM,
292    SIGPROF, SIGWINCH, SIGIO, SIGPWR, SIGSYS,
293];
294#[cfg(not(any(
295    target_os = "linux",
296    target_os = "android",
297    target_os = "fuchsia",
298    target_os = "emscripten",
299    target_os = "redox"
300)))]
301const SIGNALS: [Signal; 31] = [
302    SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGBUS, SIGFPE, SIGKILL,
303    SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGCONT,
304    SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, SIGXCPU, SIGXFSZ, SIGVTALRM,
305    SIGPROF, SIGWINCH, SIGIO, SIGSYS, SIGEMT, SIGINFO,
306];
307
308pub const NSIG: i32 = 32;
309
310/// Iterator over all valid signals for the current platform
311#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
312pub struct SignalIterator {
313    next: usize,
314}
315
316impl Iterator for SignalIterator {
317    type Item = Signal;
318
319    fn next(&mut self) -> Option<Signal> {
320        if self.next < SIGNALS.len() {
321            let next_signal = SIGNALS[self.next];
322            self.next += 1;
323            Some(next_signal)
324        } else {
325            None
326        }
327    }
328}
329
330impl Signal {
331    pub fn iterator() -> SignalIterator {
332        SignalIterator { next: 0 }
333    }
334}
335
336impl TryFrom<i32> for Signal {
337    type Error = InvalidSignal;
338
339    fn try_from(signum: i32) -> Result<Signal, InvalidSignal> {
340        if 0 < signum && signum < NSIG {
341            Ok(unsafe { mem::transmute::<i32, Signal>(signum) })
342        } else {
343            Err(InvalidSignal)
344        }
345    }
346}
347
348pub const SIGIOT: Signal = SIGABRT;
349pub const SIGPOLL: Signal = SIGIO;
350pub const SIGUNUSED: Signal = SIGSYS;