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}