@@ -40,10 +40,14 @@ fn SIGRTMAX() -> c_int {
40
40
/// Verifies that a signal number is valid when sent to a vCPU.
41
41
///
42
42
/// VCPU signals need to have values enclosed within the OS limits for realtime signals.
43
+ /// Returns either `Ok(num)` or `Err(EINVAL)`.
43
44
///
44
- /// Will return Ok(num) or Err(EINVAL).
45
- fn validate_vcpu_signal_num ( num : c_int ) -> io:: Result < c_int > {
46
- let actual_num = num + SIGRTMIN ( ) ;
45
+ /// # Arguments
46
+ ///
47
+ /// * `signum`: signal number.
48
+ ///
49
+ fn validate_vcpu_signal_num ( signum : c_int ) -> io:: Result < c_int > {
50
+ let actual_num = signum + SIGRTMIN ( ) ;
47
51
if actual_num <= SIGRTMAX ( ) {
48
52
Ok ( actual_num)
49
53
} else {
@@ -54,8 +58,12 @@ fn validate_vcpu_signal_num(num: c_int) -> io::Result<c_int> {
54
58
/// Verifies that a signal number is valid when sent to the process.
55
59
///
56
60
/// Signals can take values between `SIGHUB` and `SIGSYS`.
61
+ /// Returns either `Ok(num)` or `Err(EINVAL)`.
62
+ ///
63
+ /// # Arguments
64
+ ///
65
+ /// * `signum`: signal number.
57
66
///
58
- /// Will return Ok(num) or Err(EINVAL).
59
67
fn validate_signal_num ( num : c_int ) -> io:: Result < c_int > {
60
68
if num >= SIGHUP && num <= SIGSYS {
61
69
Ok ( num)
@@ -68,6 +76,34 @@ fn validate_signal_num(num: c_int) -> io::Result<c_int> {
68
76
///
69
77
/// This is considered unsafe because the given handler will be called asynchronously, interrupting
70
78
/// whatever the thread was doing and therefore must only do async-signal-safe operations.
79
+ ///
80
+ /// # Arguments
81
+ ///
82
+ /// * `signum`: signal number.
83
+ /// * `handler`: signal handler functor.
84
+ ///
85
+ /// # Example
86
+ ///
87
+ /// ```
88
+ /// extern crate libc;
89
+ /// extern crate sys_util;
90
+ ///
91
+ /// use libc::{c_int, c_void, raise, siginfo_t};
92
+ /// use sys_util::register_vcpu_signal_handler;
93
+ ///
94
+ /// extern "C" fn handle_signal(_: c_int, _: *mut siginfo_t, _: *mut c_void) {}
95
+ /// extern "C" { fn __libc_current_sigrtmin() -> c_int; }
96
+ ///
97
+ /// fn main() {
98
+ /// // Register dummy signal handler for `SIGRTMIN`.
99
+ /// assert!(unsafe { register_vcpu_signal_handler(0, handle_signal).is_ok() });
100
+ /// // Raise `SIGRTMIN`.
101
+ /// unsafe { raise(__libc_current_sigrtmin()); }
102
+ /// // Assert that the process is still alive.
103
+ /// assert!(true);
104
+ /// }
105
+ /// ```
106
+ ///
71
107
pub unsafe fn register_vcpu_signal_handler (
72
108
signum : c_int ,
73
109
handler : SignalHandler ,
@@ -81,6 +117,34 @@ pub unsafe fn register_vcpu_signal_handler(
81
117
}
82
118
83
119
/// Registers `handler` as the process' signal handler of `signum`.
120
+ ///
121
+ /// # Arguments
122
+ ///
123
+ /// * `signum`: signal number.
124
+ /// * `handler`: signal handler functor.
125
+ ///
126
+ /// # Example
127
+ ///
128
+ /// ```
129
+ /// extern crate libc;
130
+ /// extern crate sys_util;
131
+ ///
132
+ /// use std::sync::atomic::{AtomicBool, Ordering, ATOMIC_BOOL_INIT};
133
+ /// use libc::{c_int, c_void, raise, siginfo_t, SIGUSR1};
134
+ /// use sys_util::register_signal_handler;
135
+ ///
136
+ /// static HANDLER_CALLED: AtomicBool = ATOMIC_BOOL_INIT;
137
+ /// extern "C" fn handle_signal(_: c_int, _: *mut siginfo_t, _: *mut c_void) {
138
+ /// HANDLER_CALLED.store(true, Ordering::SeqCst);
139
+ /// }
140
+ ///
141
+ /// fn main() {
142
+ /// assert!(unsafe { register_signal_handler(SIGUSR1, handle_signal).is_ok() });
143
+ /// unsafe { raise(SIGUSR1); }
144
+ /// assert!(HANDLER_CALLED.load(Ordering::SeqCst));
145
+ /// }
146
+ /// ```
147
+ ///
84
148
pub fn register_signal_handler ( signum : c_int , handler : SignalHandler ) -> Result < ( ) , io:: Error > {
85
149
let num = validate_signal_num ( signum) ?;
86
150
// Safe, because this is a POD struct.
0 commit comments