1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
//! # signal-stack //! //! Low-level library for installing signal handlers. Signal handlers are //! modelled as a stack: when a signal is raised, the stack is traversed //! from top to bottom, and each signal handler is called in turn. //! //! A signal handler can return `true` to indicate that the signal was //! handled. In this case, no further handlers will be called. If no //! signal handler returns `true` then the default behaviour for that //! signal will occur. #![deny(missing_docs)] use std::sync::Arc; use libc::c_int; mod backend; mod signal_safe; mod stack; pub use stack::Handler; /// A type may implement this trait to indicate that it can be converted /// into an async-signal-safe function. ie. one that is safe to call from /// a signal handler. pub unsafe trait SafeHandler: Into<Arc<dyn Handler>> {} /// This is the primary interface to the crate. When this guard is constructed /// a new signal handler for one or more signals is pushed onto the top of the /// stack. /// /// When it is dropped, the signal handler will be removed from the stack. /// Signal handlers can be removed at any time, it need not be in reverse /// order, although that would typically be the case. #[derive(Debug)] pub struct SignalHandlerGuard<'a> { signums: &'a [c_int], handler_id: stack::HandlerId, } impl<'a> SignalHandlerGuard<'a> { /// Add a new signal handler. /// /// # Safety /// The handler function *must* be `async-signal-safe`, which places severe /// restrictions on what the function may do. /// /// A non-exhaustive list of things that are not allowed: /// - Allocating or freeing memory. /// - Locking or unlocking mutexes or other kinds of concurrency primitive, /// with the exception of posting to a `libc` semaphore. /// - Calling a function which is not itself marked as async-signal-safe. /// - Performing any kind of blocking I/O. pub unsafe fn new_unsafe(signums: &'a [c_int], handler: Arc<dyn Handler>) -> Self { Self { signums, handler_id: stack::add_handler(signums, handler), } } /// Safely construct a signal guard from a function known statically to be /// async-signal-safe. pub fn new<H: SafeHandler>(signums: &'a [c_int], handler: H) -> Self { unsafe { Self::new_unsafe(signums, handler.into()) } } /// Forget this signal guard: the handler will remain attached for the lifetime /// of the program. pub fn forget(mut self) { self.signums = &[]; } } impl<'a> Drop for SignalHandlerGuard<'a> { fn drop(&mut self) { unsafe { stack::remove_handler(self.signums, &self.handler_id); } } }