@@ -542,6 +542,79 @@ pub unsafe fn sigaction(signal: Signal, sigaction: &SigAction) -> Result<SigActi
542
542
Errno :: result ( res) . map ( |_| SigAction { sigaction : oldact } )
543
543
}
544
544
545
+ /// Signal management (see [signal(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/signal.html))
546
+ ///
547
+ /// Installs `handler` for the given `signal`, returning the previous signal
548
+ /// handler. `signal` should only be used following another call to `signal` or
549
+ /// if the current handler is the default. The return value of `signal` is
550
+ /// undefined after setting the handler with [`sigaction`][SigActionFn].
551
+ ///
552
+ /// # Safety
553
+ ///
554
+ /// If the pointer to the previous signal handler is invalid, undefined
555
+ /// behavior could be invoked when casting it back to a [`SigAction`][SigActionStruct].
556
+ ///
557
+ /// # Examples
558
+ ///
559
+ /// Ignore `SIGINT`:
560
+ ///
561
+ /// ```no_run
562
+ /// # use nix::sys::signal::{self, Signal, SigHandler};
563
+ /// unsafe { signal::signal(Signal::SIGINT, SigHandler::SigIgn) }.unwrap();
564
+ /// ```
565
+ ///
566
+ /// Use a signal handler to set a flag variable:
567
+ ///
568
+ /// ```no_run
569
+ /// # #[macro_use] extern crate lazy_static;
570
+ /// # extern crate libc;
571
+ /// # extern crate nix;
572
+ /// # use std::sync::atomic::{AtomicBool, Ordering};
573
+ /// # use nix::sys::signal::{self, Signal, SigHandler};
574
+ /// lazy_static! {
575
+ /// static ref SIGNALED: AtomicBool = AtomicBool::new(false);
576
+ /// }
577
+ ///
578
+ /// extern fn handle_sigint(signal: libc::c_int) {
579
+ /// let signal = Signal::from_c_int(signal).unwrap();
580
+ /// SIGNALED.store(signal == Signal::SIGINT, Ordering::Relaxed);
581
+ /// }
582
+ ///
583
+ /// fn main() {
584
+ /// let handler = SigHandler::Handler(handle_sigint);
585
+ /// unsafe { signal::signal(Signal::SIGINT, handler) }.unwrap();
586
+ /// }
587
+ /// ```
588
+ ///
589
+ /// # Errors
590
+ ///
591
+ /// Returns [`Error::UnsupportedOperation`] if `handler` is
592
+ /// [`SigAction`][SigActionStruct]. Use [`sigaction`][SigActionFn] instead.
593
+ ///
594
+ /// `signal` also returns any error from `libc::signal`, such as when an attempt
595
+ /// is made to catch a signal that cannot be caught or to ignore a signal that
596
+ /// cannot be ignored.
597
+ ///
598
+ /// [`Error::UnsupportedOperation`]: ../../enum.Error.html#variant.UnsupportedOperation
599
+ /// [SigActionStruct]: struct.SigAction.html
600
+ /// [sigactionFn]: fn.sigaction.html
601
+ pub unsafe fn signal ( signal : Signal , handler : SigHandler ) -> Result < SigHandler > {
602
+ let signal = signal as libc:: c_int ;
603
+ let res = match handler {
604
+ SigHandler :: SigDfl => libc:: signal ( signal, libc:: SIG_DFL ) ,
605
+ SigHandler :: SigIgn => libc:: signal ( signal, libc:: SIG_IGN ) ,
606
+ SigHandler :: Handler ( handler) => libc:: signal ( signal, handler as libc:: sighandler_t ) ,
607
+ SigHandler :: SigAction ( _) => return Err ( Error :: UnsupportedOperation ) ,
608
+ } ;
609
+ Errno :: result ( res) . map ( |oldhandler| {
610
+ match oldhandler {
611
+ libc:: SIG_DFL => SigHandler :: SigDfl ,
612
+ libc:: SIG_IGN => SigHandler :: SigIgn ,
613
+ f => SigHandler :: Handler ( mem:: transmute ( f) ) ,
614
+ }
615
+ } )
616
+ }
617
+
545
618
/// Manages the signal mask (set of blocked signals) for the calling thread.
546
619
///
547
620
/// If the `set` parameter is `Some(..)`, then the signal mask will be updated with the signal set.
0 commit comments