Skip to content

Commit 95f5d7e

Browse files
author
Alexandra Iordache
committed
documentation & doctests for signal handling utils
Signed-off-by: Alexandra Iordache <[email protected]>
1 parent f533bf1 commit 95f5d7e

File tree

2 files changed

+77
-4
lines changed

2 files changed

+77
-4
lines changed

sys_util/src/signal.rs

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,14 @@ fn SIGRTMAX() -> c_int {
4040
/// Verifies that a signal number is valid when sent to a vCPU.
4141
///
4242
/// VCPU signals need to have values enclosed within the OS limits for realtime signals.
43+
/// Returns either `Ok(num)` or `Err(EINVAL)`.
4344
///
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();
4751
if actual_num <= SIGRTMAX() {
4852
Ok(actual_num)
4953
} else {
@@ -54,8 +58,12 @@ fn validate_vcpu_signal_num(num: c_int) -> io::Result<c_int> {
5458
/// Verifies that a signal number is valid when sent to the process.
5559
///
5660
/// Signals can take values between `SIGHUB` and `SIGSYS`.
61+
/// Returns either `Ok(num)` or `Err(EINVAL)`.
62+
///
63+
/// # Arguments
64+
///
65+
/// * `signum`: signal number.
5766
///
58-
/// Will return Ok(num) or Err(EINVAL).
5967
fn validate_signal_num(num: c_int) -> io::Result<c_int> {
6068
if num >= SIGHUP && num <= SIGSYS {
6169
Ok(num)
@@ -68,6 +76,34 @@ fn validate_signal_num(num: c_int) -> io::Result<c_int> {
6876
///
6977
/// This is considered unsafe because the given handler will be called asynchronously, interrupting
7078
/// 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+
///
71107
pub unsafe fn register_vcpu_signal_handler(
72108
signum: c_int,
73109
handler: SignalHandler,
@@ -81,6 +117,34 @@ pub unsafe fn register_vcpu_signal_handler(
81117
}
82118

83119
/// 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+
///
84148
pub fn register_signal_handler(signum: c_int, handler: SignalHandler) -> Result<(), io::Error> {
85149
let num = validate_signal_num(signum)?;
86150
// Safe, because this is a POD struct.

vmm/src/signal_handler.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ const SI_OFF_SYSCALL: isize = 6;
2121

2222
const SYS_SECCOMP_CODE: i32 = 1;
2323

24+
/// Signal handler for `SIGSYS`.
25+
///
26+
/// Increments the `seccomp.num_faults` metric, logs an error message and terminates the process
27+
/// with a specific exit code.
28+
///
2429
extern "C" fn sigsys_handler(num: c_int, info: *mut siginfo_t, _unused: *mut c_void) {
2530
// Safe because we're just reading some fields from a supposedly valid argument.
2631
let si_signo = unsafe { (*info).si_signo };
@@ -53,6 +58,10 @@ extern "C" fn sigsys_handler(num: c_int, info: *mut siginfo_t, _unused: *mut c_v
5358
};
5459
}
5560

61+
/// Signal handler for `SIGBUS` and `SIGSEGV`.
62+
///
63+
/// Logs an error message and terminates the process with a specific exit code.
64+
///
5665
extern "C" fn sigbus_sigsegv_handler(num: c_int, info: *mut siginfo_t, _unused: *mut c_void) {
5766
// Safe because we're just reading some fields from a supposedly valid argument.
5867
let si_signo = unsafe { (*info).si_signo };

0 commit comments

Comments
 (0)