1#![allow(unsafe_code)]
13
14use crate::backend::c;
15use core::fmt;
16use core::num::NonZeroI32;
17
18#[doc(alias = "SIGRTMIN")]
45#[doc(alias = "SIGRTMAX")]
46#[derive(Copy, Clone, Eq, PartialEq)]
47#[repr(transparent)]
48pub struct Signal(NonZeroI32);
49
50#[rustfmt::skip]
52impl Signal {
53 pub const HUP: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGHUP) });
55 pub const INT: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGINT) });
57 pub const QUIT: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGQUIT) });
59 pub const ILL: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGILL) });
61 pub const TRAP: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGTRAP) });
63 #[doc(alias = "IOT")]
65 #[doc(alias = "ABRT")]
66 pub const ABORT: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGABRT) });
67 pub const BUS: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGBUS) });
69 pub const FPE: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGFPE) });
71 pub const KILL: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGKILL) });
73 #[cfg(not(target_os = "vita"))]
75 pub const USR1: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGUSR1) });
76 pub const SEGV: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGSEGV) });
78 #[cfg(not(target_os = "vita"))]
80 pub const USR2: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGUSR2) });
81 pub const PIPE: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGPIPE) });
83 #[doc(alias = "ALRM")]
85 pub const ALARM: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGALRM) });
86 pub const TERM: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGTERM) });
88 #[cfg(not(any(
90 bsd,
91 solarish,
92 target_os = "aix",
93 target_os = "cygwin",
94 target_os = "haiku",
95 target_os = "horizon",
96 target_os = "hurd",
97 target_os = "nto",
98 target_os = "vita",
99 all(
100 linux_kernel,
101 any(
102 target_arch = "mips",
103 target_arch = "mips32r6",
104 target_arch = "mips64",
105 target_arch = "mips64r6",
106 target_arch = "sparc",
107 target_arch = "sparc64"
108 ),
109 ),
110 )))]
111 pub const STKFLT: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGSTKFLT) });
112 #[cfg(not(target_os = "vita"))]
114 #[doc(alias = "CHLD")]
115 pub const CHILD: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGCHLD) });
116 #[cfg(not(target_os = "vita"))]
118 pub const CONT: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGCONT) });
119 #[cfg(not(target_os = "vita"))]
121 pub const STOP: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGSTOP) });
122 #[cfg(not(target_os = "vita"))]
124 pub const TSTP: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGTSTP) });
125 #[cfg(not(target_os = "vita"))]
127 pub const TTIN: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGTTIN) });
128 #[cfg(not(target_os = "vita"))]
130 pub const TTOU: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGTTOU) });
131 #[cfg(not(target_os = "vita"))]
133 pub const URG: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGURG) });
134 #[cfg(not(target_os = "vita"))]
136 pub const XCPU: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGXCPU) });
137 #[cfg(not(target_os = "vita"))]
139 pub const XFSZ: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGXFSZ) });
140 #[cfg(not(target_os = "vita"))]
142 #[doc(alias = "VTALRM")]
143 pub const VTALARM: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGVTALRM) });
144 #[cfg(not(target_os = "vita"))]
146 pub const PROF: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGPROF) });
147 #[cfg(not(target_os = "vita"))]
149 pub const WINCH: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGWINCH) });
150 #[doc(alias = "POLL")]
152 #[cfg(not(any(target_os = "haiku", target_os = "vita")))]
153 pub const IO: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGIO) });
154 #[cfg(not(any(
156 bsd,
157 target_os = "haiku",
158 target_os = "horizon",
159 target_os = "hurd",
160 target_os = "vita"
161 )))]
162 #[doc(alias = "PWR")]
163 pub const POWER: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGPWR) });
164 #[doc(alias = "UNUSED")]
166 pub const SYS: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGSYS) });
167 #[cfg(any(
169 bsd,
170 solarish,
171 target_os = "aix",
172 target_os = "hermit",
173 all(
174 linux_kernel,
175 any(
176 target_arch = "mips",
177 target_arch = "mips32r6",
178 target_arch = "mips64",
179 target_arch = "mips64r6",
180 target_arch = "sparc",
181 target_arch = "sparc64"
182 )
183 )
184 ))]
185 pub const EMT: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGEMT) });
186 #[cfg(bsd)]
188 pub const INFO: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGINFO) });
189 #[cfg(target_os = "freebsd")]
191 #[doc(alias = "LWP")]
192 pub const THR: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGTHR) });
193 #[cfg(target_os = "freebsd")]
195 pub const LIBRT: Self = Self(unsafe { NonZeroI32::new_unchecked(c::SIGLIBRT) });
196}
197
198impl Signal {
199 #[inline]
203 pub const fn as_raw(self) -> i32 {
204 self.0.get()
205 }
206
207 #[inline]
209 pub const fn as_raw_nonzero(self) -> NonZeroI32 {
210 self.0
211 }
212
213 #[inline]
232 pub const unsafe fn from_raw_unchecked(sig: i32) -> Self {
233 Self::from_raw_nonzero_unchecked(NonZeroI32::new_unchecked(sig))
234 }
235
236 #[inline]
255 pub const unsafe fn from_raw_nonzero_unchecked(sig: NonZeroI32) -> Self {
256 Self(sig)
257 }
258
259 pub const fn from_named_raw(sig: i32) -> Option<Self> {
272 if let Some(sig) = NonZeroI32::new(sig) {
273 Self::from_named_raw_nonzero(sig)
274 } else {
275 None
276 }
277 }
278
279 pub const fn from_named_raw_nonzero(sig: NonZeroI32) -> Option<Self> {
292 match sig.get() {
293 c::SIGHUP => Some(Self::HUP),
294 c::SIGINT => Some(Self::INT),
295 c::SIGQUIT => Some(Self::QUIT),
296 c::SIGILL => Some(Self::ILL),
297 c::SIGTRAP => Some(Self::TRAP),
298 c::SIGABRT => Some(Self::ABORT),
299 c::SIGBUS => Some(Self::BUS),
300 c::SIGFPE => Some(Self::FPE),
301 c::SIGKILL => Some(Self::KILL),
302 #[cfg(not(target_os = "vita"))]
303 c::SIGUSR1 => Some(Self::USR1),
304 c::SIGSEGV => Some(Self::SEGV),
305 #[cfg(not(target_os = "vita"))]
306 c::SIGUSR2 => Some(Self::USR2),
307 c::SIGPIPE => Some(Self::PIPE),
308 c::SIGALRM => Some(Self::ALARM),
309 c::SIGTERM => Some(Self::TERM),
310 #[cfg(not(any(
311 bsd,
312 solarish,
313 target_os = "aix",
314 target_os = "cygwin",
315 target_os = "haiku",
316 target_os = "horizon",
317 target_os = "hurd",
318 target_os = "nto",
319 target_os = "vita",
320 all(
321 linux_kernel,
322 any(
323 target_arch = "mips",
324 target_arch = "mips32r6",
325 target_arch = "mips64",
326 target_arch = "mips64r6",
327 target_arch = "sparc",
328 target_arch = "sparc64"
329 ),
330 )
331 )))]
332 c::SIGSTKFLT => Some(Self::STKFLT),
333 #[cfg(not(target_os = "vita"))]
334 c::SIGCHLD => Some(Self::CHILD),
335 #[cfg(not(target_os = "vita"))]
336 c::SIGCONT => Some(Self::CONT),
337 #[cfg(not(target_os = "vita"))]
338 c::SIGSTOP => Some(Self::STOP),
339 #[cfg(not(target_os = "vita"))]
340 c::SIGTSTP => Some(Self::TSTP),
341 #[cfg(not(target_os = "vita"))]
342 c::SIGTTIN => Some(Self::TTIN),
343 #[cfg(not(target_os = "vita"))]
344 c::SIGTTOU => Some(Self::TTOU),
345 #[cfg(not(target_os = "vita"))]
346 c::SIGURG => Some(Self::URG),
347 #[cfg(not(target_os = "vita"))]
348 c::SIGXCPU => Some(Self::XCPU),
349 #[cfg(not(target_os = "vita"))]
350 c::SIGXFSZ => Some(Self::XFSZ),
351 #[cfg(not(target_os = "vita"))]
352 c::SIGVTALRM => Some(Self::VTALARM),
353 #[cfg(not(target_os = "vita"))]
354 c::SIGPROF => Some(Self::PROF),
355 #[cfg(not(target_os = "vita"))]
356 c::SIGWINCH => Some(Self::WINCH),
357 #[cfg(not(any(target_os = "haiku", target_os = "vita")))]
358 c::SIGIO => Some(Self::IO),
359 #[cfg(not(any(
360 bsd,
361 target_os = "haiku",
362 target_os = "horizon",
363 target_os = "hurd",
364 target_os = "vita"
365 )))]
366 c::SIGPWR => Some(Self::POWER),
367 c::SIGSYS => Some(Self::SYS),
368 #[cfg(any(
369 bsd,
370 solarish,
371 target_os = "aix",
372 target_os = "hermit",
373 all(
374 linux_kernel,
375 any(
376 target_arch = "mips",
377 target_arch = "mips32r6",
378 target_arch = "mips64",
379 target_arch = "mips64r6",
380 target_arch = "sparc",
381 target_arch = "sparc64"
382 )
383 )
384 ))]
385 c::SIGEMT => Some(Self::EMT),
386 #[cfg(bsd)]
387 c::SIGINFO => Some(Self::INFO),
388 #[cfg(target_os = "freebsd")]
389 c::SIGTHR => Some(Self::THR),
390 #[cfg(target_os = "freebsd")]
391 c::SIGLIBRT => Some(Self::LIBRT),
392
393 _ => None,
394 }
395 }
396}
397
398impl fmt::Debug for Signal {
399 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
400 match *self {
401 Self::HUP => "Signal::HUP".fmt(f),
402 Self::INT => "Signal::INT".fmt(f),
403 Self::QUIT => "Signal::QUIT".fmt(f),
404 Self::ILL => "Signal::ILL".fmt(f),
405 Self::TRAP => "Signal::TRAP".fmt(f),
406 Self::ABORT => "Signal::ABORT".fmt(f),
407 Self::BUS => "Signal::BUS".fmt(f),
408 Self::FPE => "Signal::FPE".fmt(f),
409 Self::KILL => "Signal::KILL".fmt(f),
410 #[cfg(not(target_os = "vita"))]
411 Self::USR1 => "Signal::USR1".fmt(f),
412 Self::SEGV => "Signal::SEGV".fmt(f),
413 #[cfg(not(target_os = "vita"))]
414 Self::USR2 => "Signal::USR2".fmt(f),
415 Self::PIPE => "Signal::PIPE".fmt(f),
416 Self::ALARM => "Signal::ALARM".fmt(f),
417 Self::TERM => "Signal::TERM".fmt(f),
418 #[cfg(not(any(
419 bsd,
420 solarish,
421 target_os = "aix",
422 target_os = "cygwin",
423 target_os = "haiku",
424 target_os = "horizon",
425 target_os = "hurd",
426 target_os = "nto",
427 target_os = "vita",
428 all(
429 linux_kernel,
430 any(
431 target_arch = "mips",
432 target_arch = "mips32r6",
433 target_arch = "mips64",
434 target_arch = "mips64r6",
435 target_arch = "sparc",
436 target_arch = "sparc64"
437 ),
438 ),
439 )))]
440 Self::STKFLT => "Signal::STKFLT".fmt(f),
441 #[cfg(not(target_os = "vita"))]
442 Self::CHILD => "Signal::CHILD".fmt(f),
443 #[cfg(not(target_os = "vita"))]
444 Self::CONT => "Signal::CONT".fmt(f),
445 #[cfg(not(target_os = "vita"))]
446 Self::STOP => "Signal::STOP".fmt(f),
447 #[cfg(not(target_os = "vita"))]
448 Self::TSTP => "Signal::TSTP".fmt(f),
449 #[cfg(not(target_os = "vita"))]
450 Self::TTIN => "Signal::TTIN".fmt(f),
451 #[cfg(not(target_os = "vita"))]
452 Self::TTOU => "Signal::TTOU".fmt(f),
453 #[cfg(not(target_os = "vita"))]
454 Self::URG => "Signal::URG".fmt(f),
455 #[cfg(not(target_os = "vita"))]
456 Self::XCPU => "Signal::XCPU".fmt(f),
457 #[cfg(not(target_os = "vita"))]
458 Self::XFSZ => "Signal::XFSZ".fmt(f),
459 #[cfg(not(target_os = "vita"))]
460 Self::VTALARM => "Signal::VTALARM".fmt(f),
461 #[cfg(not(target_os = "vita"))]
462 Self::PROF => "Signal::PROF".fmt(f),
463 #[cfg(not(target_os = "vita"))]
464 Self::WINCH => "Signal::WINCH".fmt(f),
465 #[cfg(not(any(target_os = "haiku", target_os = "vita")))]
466 Self::IO => "Signal::IO".fmt(f),
467 #[cfg(not(any(
468 bsd,
469 target_os = "haiku",
470 target_os = "horizon",
471 target_os = "hurd",
472 target_os = "vita"
473 )))]
474 Self::POWER => "Signal::POWER".fmt(f),
475 Self::SYS => "Signal::SYS".fmt(f),
476 #[cfg(any(
477 bsd,
478 solarish,
479 target_os = "aix",
480 target_os = "hermit",
481 all(
482 linux_kernel,
483 any(
484 target_arch = "mips",
485 target_arch = "mips32r6",
486 target_arch = "mips64",
487 target_arch = "mips64r6",
488 target_arch = "sparc",
489 target_arch = "sparc64"
490 )
491 )
492 ))]
493 Self::EMT => "Signal::EMT".fmt(f),
494 #[cfg(bsd)]
495 Self::INFO => "Signal::INFO".fmt(f),
496 #[cfg(target_os = "freebsd")]
497 Self::THR => "Signal::THR".fmt(f),
498 #[cfg(target_os = "freebsd")]
499 Self::LIBRT => "Signal::LIBRT".fmt(f),
500
501 n => {
502 "Signal::from_raw(".fmt(f)?;
503 n.as_raw().fmt(f)?;
504 ")".fmt(f)
505 }
506 }
507 }
508}
509
510#[cfg(test)]
511mod tests {
512 use super::*;
513
514 #[test]
515 fn test_basics() {
516 assert_eq!(Signal::HUP.as_raw(), libc::SIGHUP);
517 unsafe {
518 assert_eq!(Signal::from_raw_unchecked(libc::SIGHUP), Signal::HUP);
519 assert_eq!(
520 Signal::from_raw_nonzero_unchecked(NonZeroI32::new(libc::SIGHUP).unwrap()),
521 Signal::HUP
522 );
523 }
524 }
525
526 #[test]
527 fn test_named() {
528 assert_eq!(Signal::from_named_raw(-1), None);
529 assert_eq!(Signal::from_named_raw(0), None);
530 assert_eq!(Signal::from_named_raw(c::SIGHUP), Some(Signal::HUP));
531 assert_eq!(Signal::from_named_raw(c::SIGSEGV), Some(Signal::SEGV));
532 assert_eq!(Signal::from_named_raw(c::SIGSYS), Some(Signal::SYS));
533 #[cfg(any(linux_like, solarish, target_os = "hurd"))]
534 {
535 assert_eq!(Signal::from_named_raw(libc::SIGRTMIN()), None);
536 assert_eq!(Signal::from_named_raw(libc::SIGRTMAX()), None);
537 }
538 }
539}