proc_result/unix/
signal.rs

1use core::fmt::Display;
2
3/// A Unix-like signal.
4///
5/// Represents a signal that can be sent to or received by processes on Unix-like systems.
6#[derive(Clone, Copy, Debug, PartialEq, Eq)]
7#[cfg_attr(
8    feature = "serde",
9    derive(serde::Serialize, serde::Deserialize),
10    serde(transparent)
11)]
12pub struct Signal(u8);
13
14impl Signal {
15    /// Creates a new `UnixTerminationSignal` from the underlying `u8` signal number.
16    #[must_use]
17    pub const fn from_raw(signal: u8) -> Self {
18        Self(signal)
19    }
20
21    /// Returns the underlying `u8` signal number.
22    #[must_use]
23    pub const fn to_raw(&self) -> u8 {
24        self.0
25    }
26
27    /// Null signal.
28    ///
29    /// Corresponds to signal number `0`.
30    ///
31    /// Can be used to check if a process exists without sending an actual signal.
32    pub const NULL: Self = Self(0);
33
34    /// Hangup (`SIGHUP`).
35    ///
36    /// Corresponds to signal number `1`.
37    ///
38    /// Sent to a process when its controlling terminal is closed or when a parent process exits,
39    /// often used by daemons to re-read configuration files.
40    pub const HANGUP: Self = Self(1);
41
42    /// Interrupt (`SIGINT`).
43    ///
44    /// Corresponds to signal number `2`.
45    ///
46    /// Sent by the terminal to the foreground process group to request its termination,
47    /// often initiated by the user pressing `Ctrl+C`.
48    pub const INTERRUPT: Self = Self(2);
49
50    /// Quit (`SIGQUIT`).
51    ///
52    /// Corresponds to signal number `3`.
53    ///
54    /// Sent by the terminal to the foreground process group (often by pressing `Ctrl+\`).
55    /// Typically causes a core dump and process termination.
56    pub const QUIT: Self = Self(3);
57
58    /// Illegal instruction (`SIGILL`).
59    ///
60    /// Corresponds to signal number `4`.
61    ///
62    /// Indicates an attempt to execute an invalid or malformed instruction.
63    pub const ILLEGAL_INSTRUCTION: Self = Self(4);
64
65    /// Trace trap (`SIGTRAP`).
66    ///
67    /// Corresponds to signal number `5`.
68    ///
69    /// Used by debuggers to implement breakpoints.
70    pub const TRAP: Self = Self(5);
71
72    /// Abort (`SIGABRT`).
73    ///
74    /// Corresponds to signal number `6`.
75    ///
76    /// Sent by the `abort()` function (or `_exit()` in some cases) to indicate an abnormal
77    /// termination, typically due to a detected internal inconsistency. Often causes a core dump.
78    pub const ABORT: Self = Self(6);
79
80    /// Bus error (`SIGBUS`).
81    ///
82    /// Corresponds to signal number `7`.
83    ///
84    /// Indicates a memory access error, often due to misaligned access or non-existent physical address.
85    pub const BUS_ERROR: Self = Self(7);
86
87    /// Floating-point exception (`SIGFPE`).
88    ///
89    /// Corresponds to signal number `8`.
90    ///
91    /// Indicates an erroneous arithmetic operation (e.g., division by zero, overflow).
92    pub const FLOATING_POINT_EXCEPTION: Self = Self(8);
93
94    /// Kill (`SIGKILL`).
95    ///
96    /// Corresponds to signal number `9`.
97    ///
98    /// Unconditionally terminates a process. This signal cannot be caught, blocked, or ignored,
99    /// making it the most forceful way to kill a process.
100    pub const KILL: Self = Self(9);
101
102    /// User-defined signal 1 (`SIGUSR1`).
103    ///
104    /// Corresponds to signal number `10` (often).
105    ///
106    /// A custom signal for application-specific use. Its exact number can vary by system.
107    pub const USER1: Self = Self(10); // Note: Number might vary (often 10 or 30)
108
109    /// Segmentation violation (`SIGSEGV`).
110    ///
111    /// Corresponds to signal number `11`.
112    ///
113    /// Indicates an invalid memory access (e.g., trying to write to read-only memory, or access
114    /// outside allocated bounds). Typically causes a core dump.
115    pub const SEGMENTATION_VIOLATION: Self = Self(11);
116
117    /// User-defined signal 2 (`SIGUSR2`).
118    ///
119    /// Corresponds to signal number `12` (often).
120    ///
121    /// Another custom signal for application-specific use. Its exact number can vary by system.
122    pub const USER2: Self = Self(12); // Note: Number might vary (often 12 or 31)
123
124    /// Broken pipe (`SIGPIPE`).
125    ///
126    /// Corresponds to signal number `13`.
127    ///
128    /// Sent when a process attempts to write to a pipe, socket, or FIFO whose reading end has been
129    /// closed.
130    pub const BROKEN_PIPE: Self = Self(13);
131
132    /// Alarm clock (`SIGALRM`).
133    ///
134    /// Corresponds to signal number `14`.
135    ///
136    /// Generated by the `alarm()` system call for timer expiration.
137    pub const ALARM: Self = Self(14);
138
139    /// Termination (`SIGTERM`).
140    ///
141    /// Corresponds to signal number `15`.
142    ///
143    /// A generic request to terminate a process. Unlike `SIGKILL`, this signal can be caught and
144    /// handled by the process to perform cleanup before exiting gracefully.
145    pub const TERMINATION: Self = Self(15);
146
147    /// Stack fault (`SIGSTKFLT`).
148    ///
149    /// Corresponds to signal number `16`.
150    ///
151    /// (Linux specific) Indicates a stack fault on a coprocessor. Less common.
152    pub const STACK_FAULT: Self = Self(16);
153
154    /// Child stopped or terminated (`SIGCHLD`).
155    ///
156    /// Corresponds to signal number `17`.
157    ///
158    /// Sent to a parent process when one of its child processes stops or terminates.
159    pub const CHILD: Self = Self(17);
160
161    /// Continue (`SIGCONT`).
162    ///
163    /// Corresponds to signal number `18`.
164    ///
165    /// If the process is stopped, it is resumed. If it is already running, it continues.
166    pub const CONTINUE: Self = Self(18);
167
168    /// Stop (`SIGSTOP`).
169    ///
170    /// Corresponds to signal number `19`.
171    ///
172    /// Stops a process. Unlike `SIGTSTP`, this signal cannot be caught, blocked, or ignored, making
173    /// it a forceful way to pause execution.
174    pub const STOP: Self = Self(19);
175
176    /// Tty stop (`SIGTSTP`).
177    ///
178    /// Corresponds to signal number `20`.
179    ///
180    /// Sent by the terminal to the foreground process group when the user presses `Ctrl+Z`.
181    ///
182    /// Can be caught and handled to allow the process to clean up or save state before stopping.
183    pub const TTY_STOP: Self = Self(20);
184
185    /// Background read from tty (`SIGTTIN`).
186    ///
187    /// Corresponds to signal number `21`.
188    ///
189    /// Sent to a process in the background when it attempts to read from its controlling terminal.
190    pub const TTY_IN: Self = Self(21);
191
192    /// Background write to tty (`SIGTTOU`).
193    ///
194    /// Corresponds to signal number `22`.
195    ///
196    /// Sent to a process in the background when it attempts to write to its controlling terminal.
197    pub const TTY_OUT: Self = Self(22);
198
199    /// Urgent condition on socket (`SIGURG`).
200    ///
201    /// Corresponds to signal number `23`.
202    ///
203    /// Indicates urgent data is available on a socket.
204    pub const URGENT_IO: Self = Self(23);
205
206    /// CPU time limit exceeded (`SIGXCPU`).
207    ///
208    /// Corresponds to signal number `24`.
209    ///
210    /// Sent when a process exceeds its CPU time limit.
211    pub const CPU_LIMIT: Self = Self(24);
212
213    /// File size limit exceeded (`SIGXFSZ`).
214    ///
215    /// Corresponds to signal number `25`.
216    ///
217    /// Sent when a process attempts to create a file larger than its imposed limit.
218    pub const FILE_SIZE_LIMIT: Self = Self(25);
219
220    /// Virtual alarm clock (`SIGVTALRM`).
221    ///
222    /// Corresponds to signal number `26`.
223    ///
224    /// Generated by a virtual alarm clock, often used for profiling.
225    pub const VIRTUAL_ALARM: Self = Self(26);
226
227    /// Profiling timer expired (`SIGPROF`).
228    ///
229    /// Corresponds to signal number `27`.
230    ///
231    /// Generated by a profiling timer, typically used for profiling applications.
232    pub const PROFILING_TIMER: Self = Self(27);
233
234    /// Window changed (`SIGWINCH`).
235    ///
236    /// Corresponds to signal number `28`.
237    ///
238    /// Sent to the foreground process group when the terminal window size has changed.
239    pub const WINDOW_CHANGED: Self = Self(28);
240
241    /// I/O is possible (`SIGIO`).
242    ///
243    /// Corresponds to signal number `29`.
244    ///
245    /// Indicates that asynchronous I/O is possible on a file descriptor.
246    pub const IO_POSSIBLE: Self = Self(29);
247
248    /// Power failure restart (`SIGPWR`).
249    ///
250    /// Corresponds to signal number `30`.
251    ///
252    /// (Linux specific) Indicates a power failure.
253    pub const POWER_FAILURE: Self = Self(30);
254
255    /// Bad system call (`SIGSYS`).
256    ///
257    /// Corresponds to signal number `31`.
258    ///
259    /// Indicates an invalid system call.
260    pub const BAD_SYSTEM_CALL: Self = Self(31);
261}
262
263impl From<u8> for Signal {
264    fn from(signal: u8) -> Self {
265        Signal::from_raw(signal)
266    }
267}
268
269impl Display for Signal {
270    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
271        self.0.fmt(f)
272    }
273}
274
275#[cfg(test)]
276mod tests {
277    use super::*;
278
279    #[test]
280    fn test_from_raw() {
281        assert_eq!(Signal::from_raw(1).to_raw(), 1);
282        assert_eq!(Signal::from_raw(15).to_raw(), 15);
283        assert_eq!(Signal::from_raw(31).to_raw(), 31);
284    }
285
286    #[test]
287    fn test_to_raw() {
288        let signal = Signal::HANGUP;
289        assert_eq!(signal.to_raw(), 1);
290    }
291
292    #[test]
293    fn test_from_u8() {
294        let signal: Signal = 2.into();
295        assert_eq!(signal.to_raw(), 2);
296    }
297}
298
299#[cfg(all(test, feature = "serde"))]
300mod serde_tests {
301    use super::*;
302    use serde_test::{Token, assert_tokens};
303
304    #[test]
305    fn test_serde() {
306        let signal = Signal::HANGUP;
307        assert_tokens(&signal, &[Token::U8(1)]);
308
309        let signal = Signal::from_raw(15);
310        assert_tokens(&signal, &[Token::U8(15)]);
311    }
312}