1// Copyright (c) 2023 Huawei Device Co., Ltd. 2// Licensed under the Apache License, Version 2.0 (the "License"); 3// you may not use this file except in compliance with the License. 4// You may obtain a copy of the License at 5// 6// http://www.apache.org/licenses/LICENSE-2.0 7// 8// Unless required by applicable law or agreed to in writing, software 9// distributed under the License is distributed on an "AS IS" BASIS, 10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11// See the License for the specific language governing permissions and 12// limitations under the License. 13 14#![warn(missing_docs)] 15 16//! # ylong_signal 17//! Provides methods to set or unset an action for signal handler. 18 19mod common; 20pub use common::SIGNAL_BLOCK_LIST; 21 22mod sig_map; 23mod spin_rwlock; 24#[cfg(windows)] 25mod windows; 26 27#[cfg(not(windows))] 28mod unix; 29 30use std::io; 31 32use libc::c_int; 33 34/// Registers a user-defined function for the signal action. 35/// 36/// Currently this function only supports registering one action for each 37/// signal. If another component in the process sets a signal action 38/// without using this method, this old action will be overwritten by the 39/// new registered action. After unregistering this old action will 40/// in turn overwrite the new registered ation. 41/// # Errors 42/// 43/// Calling this fuction twice on the same signal without a call to 44/// [`deregister_signal_action`] will result in an `AlreadyExists` error. 45/// 46/// Calling this function on the following signal will result in a 47/// `InvalidInput` error: 48/// - `SIGSEGV` 49/// - `SIGKILL` 50/// - `SIGSTOP` 51/// - `SIGFPE` 52/// - `SIGILL` 53/// This function doesn't support setting actions for these signals due to POSIX 54/// settings or their needs of special handling. 55/// 56/// # Safety 57/// 58/// This function is unsafe, because it sets a function to be run in a signal 59/// handler as there are a lot of limitations (async-signal-safe) on what you 60/// can do inside a signal handler. For example, you should not use blocking 61/// Mutex since it could cause the program become deadlocked. 62/// 63/// # Example 64/// ```no run 65/// let res = unsafe { 66/// ylong_signal::register_signal_action(libc::SIGTERM, move || { 67/// println!("inside SIGTERM signal handler"); 68/// }) 69/// }; 70/// assert!(res.is_ok()); 71/// ``` 72pub unsafe fn register_signal_action<F>(sig_num: c_int, handler: F) -> io::Result<()> 73where 74 F: Fn() + Sync + Send + 'static, 75{ 76 common::Signal::register_action(sig_num, move |_| handler()) 77} 78 79/// Deregisters the signal action set to a specific signal by a previous call to 80/// [`register_signal_action`]. 81/// 82/// If the signal passed in has not been set before by 83/// [`register_signal_action`], this function will do nothing. 84/// 85/// If the signal passed in has been set before by [`register_signal_action`], 86/// then the action of the signal will be dropped, and the overwritten old 87/// action will take its place. The overwrite action may fail and return an 88/// error. 89/// 90/// After calling this function, you could call [`register_signal_action`] again 91/// on the same signal. 92/// 93/// # Example 94/// ```no run 95/// ylong_signal::deregister_signal_action(libc::SIGTERM); 96/// ``` 97pub fn deregister_signal_action(sig_num: c_int) -> io::Result<()> { 98 common::Signal::deregister_action(sig_num) 99} 100 101/// Deregisters the signal handler of a signal along with all its previous 102/// registered actions. 103/// 104/// The remove of the signal handler will influence all components inside the 105/// process, therefore you should be cautious when calling this function. 106/// 107/// # Example 108/// ```no run 109/// let res = ylong_signal::deregister_signal_hook(libc::SIGTERM); 110/// assert!(res.is_ok()); 111/// ``` 112pub fn deregister_signal_hook(sig_num: c_int) -> io::Result<()> { 113 common::Signal::deregister_hook(sig_num) 114} 115