8
8
use super :: SyscallReturnCode ;
9
9
use libc:: {
10
10
c_int, c_void, pthread_kill, pthread_t, sigaction, sigfillset, siginfo_t, sigset_t, EINVAL ,
11
+ SIGHUP , SIGSYS ,
11
12
} ;
12
13
use std:: io;
13
14
use std:: mem;
@@ -36,12 +37,12 @@ fn SIGRTMAX() -> c_int {
36
37
unsafe { __libc_current_sigrtmax ( ) }
37
38
}
38
39
39
- /// Verifies that a signal number is valid.
40
+ /// Verifies that a signal number is valid when sent to a vCPU .
40
41
///
41
42
/// VCPU signals need to have values enclosed within the OS limits for realtime signals.
42
43
///
43
44
/// Will return Ok(num) or Err(EINVAL).
44
- pub fn validate_vcpu_signal_num ( num : c_int ) -> io:: Result < c_int > {
45
+ fn validate_vcpu_signal_num ( num : c_int ) -> io:: Result < c_int > {
45
46
let actual_num = num + SIGRTMIN ( ) ;
46
47
if actual_num <= SIGRTMAX ( ) {
47
48
Ok ( actual_num)
@@ -50,25 +51,42 @@ pub fn validate_vcpu_signal_num(num: c_int) -> io::Result<c_int> {
50
51
}
51
52
}
52
53
53
- /// Registers `handler` as the vCPU's signal handler of signum `num`.
54
+ /// Verifies that a signal number is valid when sent to the process.
55
+ ///
56
+ /// Signals can take values between `SIGHUB` and `SIGSYS`.
57
+ ///
58
+ /// Will return Ok(num) or Err(EINVAL).
59
+ fn validate_signal_num ( num : c_int ) -> io:: Result < c_int > {
60
+ if num >= SIGHUP && num <= SIGSYS {
61
+ Ok ( num)
62
+ } else {
63
+ Err ( io:: Error :: from_raw_os_error ( EINVAL ) )
64
+ }
65
+ }
66
+
67
+ /// Registers `handler` as the vCPU's signal handler of `signum`.
54
68
///
55
69
/// This is considered unsafe because the given handler will be called asynchronously, interrupting
56
70
/// whatever the thread was doing and therefore must only do async-signal-safe operations.
57
- pub unsafe fn register_vcpu_signal_handler ( num : i32 , handler : SignalHandler ) -> io:: Result < ( ) > {
58
- let num = validate_vcpu_signal_num ( num) ?;
71
+ pub unsafe fn register_vcpu_signal_handler (
72
+ signum : c_int ,
73
+ handler : SignalHandler ,
74
+ ) -> io:: Result < ( ) > {
75
+ let num = validate_vcpu_signal_num ( signum) ?;
59
76
// Safe, because this is a POD struct.
60
77
let mut sigact: sigaction = mem:: zeroed ( ) ;
61
78
sigact. sa_flags = libc:: SA_SIGINFO ;
62
79
sigact. sa_sigaction = handler as usize ;
63
80
SyscallReturnCode ( sigaction ( num, & sigact, null_mut ( ) ) ) . into_empty_result ( )
64
81
}
65
82
66
- /// Registers the specified signal handler for `SIGSYS`.
67
- pub fn register_sigsys_handler ( sigsys_handler : SignalHandler ) -> Result < ( ) , io:: Error > {
83
+ /// Registers `handler` as the process' signal handler of `signum`.
84
+ pub fn register_signal_handler ( signum : c_int , handler : SignalHandler ) -> Result < ( ) , io:: Error > {
85
+ let num = validate_signal_num ( signum) ?;
68
86
// Safe, because this is a POD struct.
69
87
let mut sigact: sigaction = unsafe { mem:: zeroed ( ) } ;
70
88
sigact. sa_flags = libc:: SA_SIGINFO ;
71
- sigact. sa_sigaction = sigsys_handler as usize ;
89
+ sigact. sa_sigaction = handler as usize ;
72
90
73
91
// We set all the bits of sa_mask, so all signals are blocked on the current thread while the
74
92
// SIGSYS handler is executing. Safe because the parameter is valid and we check the return
@@ -78,7 +96,7 @@ pub fn register_sigsys_handler(sigsys_handler: SignalHandler) -> Result<(), io::
78
96
}
79
97
80
98
// Safe because the parameters are valid and we check the return value.
81
- unsafe { SyscallReturnCode ( sigaction ( libc :: SIGSYS , & sigact, null_mut ( ) ) ) . into_empty_result ( ) }
99
+ unsafe { SyscallReturnCode ( sigaction ( num , & sigact, null_mut ( ) ) ) . into_empty_result ( ) }
82
100
}
83
101
84
102
/// Trait for threads that can be signalled via `pthread_kill`.
@@ -116,6 +134,8 @@ mod tests {
116
134
use std:: thread;
117
135
use std:: time:: Duration ;
118
136
137
+ use libc:: SIGSYS ;
138
+
119
139
static mut SIGNAL_HANDLER_CALLED : bool = false ;
120
140
121
141
extern "C" fn handle_signal ( _: c_int , _: * mut siginfo_t , _: * mut c_void ) {
@@ -130,7 +150,8 @@ mod tests {
130
150
// testing bad value
131
151
assert ! ( register_vcpu_signal_handler( SIGRTMAX ( ) , handle_signal) . is_err( ) ) ;
132
152
assert ! ( register_vcpu_signal_handler( 0 , handle_signal) . is_ok( ) ) ;
133
- assert ! ( register_sigsys_handler( handle_signal) . is_ok( ) ) ;
153
+ assert ! ( register_signal_handler( SIGSYS , handle_signal) . is_ok( ) ) ;
154
+ assert ! ( register_signal_handler( SIGSYS + 1 , handle_signal) . is_err( ) ) ;
134
155
}
135
156
}
136
157
0 commit comments