Skip to content

Commit 6b112d7

Browse files
author
Alexandra Iordache
committed
documentation & doctests for signal handling utils
Signed-off-by: Alexandra Iordache <[email protected]>
1 parent 0f7942d commit 6b112d7

File tree

2 files changed

+81
-4
lines changed

2 files changed

+81
-4
lines changed

sys_util/src/signal.rs

+72-4
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,25 @@ fn SIGRTMAX() -> c_int {
3636
unsafe { __libc_current_sigrtmax() }
3737
}
3838

39-
/// Verifies that a signal number is valid.
39+
/// Verifies that a signal number is valid when sent to a vCPU.
4040
///
4141
/// VCPU signals need to have values enclosed within the OS limits for realtime signals.
42+
/// Returns either `Ok(num)` or `Err(EINVAL)`.
4243
///
43-
/// Will return Ok(num) or Err(EINVAL).
44-
pub fn validate_vcpu_signal_num(num: c_int) -> io::Result<c_int> {
45-
let actual_num = num + SIGRTMIN();
44+
/// # Arguments
45+
///
46+
/// * `signum`: signal number.
47+
///
48+
/// # Example
49+
///
50+
/// ```
51+
/// use sys_util::validate_vcpu_signal_num;
52+
/// assert!(validate_vcpu_signal_num(0).is_ok());
53+
/// assert!(validate_vcpu_signal_num(32).is_err());
54+
/// ```
55+
///
56+
pub fn validate_vcpu_signal_num(signum: c_int) -> io::Result<c_int> {
57+
let actual_num = signum + SIGRTMIN();
4658
if actual_num <= SIGRTMAX() {
4759
Ok(actual_num)
4860
} else {
@@ -54,6 +66,34 @@ pub fn validate_vcpu_signal_num(num: c_int) -> io::Result<c_int> {
5466
///
5567
/// This is considered unsafe because the given handler will be called asynchronously, interrupting
5668
/// whatever the thread was doing and therefore must only do async-signal-safe operations.
69+
///
70+
/// # Arguments
71+
///
72+
/// * `signum`: signal number.
73+
/// * `handler`: signal handler functor.
74+
///
75+
/// # Example
76+
///
77+
/// ```
78+
/// extern crate libc;
79+
/// extern crate sys_util;
80+
///
81+
/// use libc::{c_int, c_void, raise, siginfo_t};
82+
/// use sys_util::register_vcpu_signal_handler;
83+
///
84+
/// extern "C" fn handle_signal(_: c_int, _: *mut siginfo_t, _: *mut c_void) {}
85+
/// extern "C" { fn __libc_current_sigrtmin() -> c_int; }
86+
///
87+
/// fn main() {
88+
/// // Register dummy signal handler for `SIGRTMIN`.
89+
/// assert!(unsafe { register_vcpu_signal_handler(0, handle_signal).is_ok() });
90+
/// // Raise `SIGRTMIN`.
91+
/// unsafe { raise(__libc_current_sigrtmin()); }
92+
/// // Assert that the process is still alive.
93+
/// assert!(true);
94+
/// }
95+
/// ```
96+
///
5797
pub unsafe fn register_vcpu_signal_handler(
5898
signum: c_int,
5999
handler: SignalHandler,
@@ -67,6 +107,34 @@ pub unsafe fn register_vcpu_signal_handler(
67107
}
68108

69109
/// Registers `handler` as the process' signal handler of `signum`.
110+
///
111+
/// # Arguments
112+
///
113+
/// * `signum`: signal number.
114+
/// * `handler`: signal handler functor.
115+
///
116+
/// # Example
117+
///
118+
/// ```
119+
/// extern crate libc;
120+
/// extern crate sys_util;
121+
///
122+
/// use std::sync::atomic::{AtomicBool, Ordering, ATOMIC_BOOL_INIT};
123+
/// use libc::{c_int, c_void, raise, siginfo_t, SIGUSR1};
124+
/// use sys_util::register_signal_handler;
125+
///
126+
/// static HANDLER_CALLED: AtomicBool = ATOMIC_BOOL_INIT;
127+
/// extern "C" fn handle_signal(_: c_int, _: *mut siginfo_t, _: *mut c_void) {
128+
/// HANDLER_CALLED.store(true, Ordering::SeqCst);
129+
/// }
130+
///
131+
/// fn main() {
132+
/// assert!(unsafe { register_signal_handler(SIGUSR1, handle_signal).is_ok() });
133+
/// unsafe { raise(SIGUSR1); }
134+
/// assert!(HANDLER_CALLED.load(Ordering::SeqCst));
135+
/// }
136+
/// ```
137+
///
70138
pub fn register_signal_handler(signum: c_int, handler: SignalHandler) -> Result<(), io::Error> {
71139
// Safe, because this is a POD struct.
72140
let mut sigact: sigaction = unsafe { mem::zeroed() };

vmm/src/signal_handler.rs

+9
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)