summaryrefslogtreecommitdiff
path: root/src/sys/signal.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/sys/signal.rs')
-rw-r--r--src/sys/signal.rs109
1 files changed, 61 insertions, 48 deletions
diff --git a/src/sys/signal.rs b/src/sys/signal.rs
index 51df7b12..41a62e6a 100644
--- a/src/sys/signal.rs
+++ b/src/sys/signal.rs
@@ -335,17 +335,17 @@ pub struct SigSet {
impl SigSet {
pub fn all() -> SigSet {
- let mut sigset: libc::sigset_t = unsafe { mem::uninitialized() };
- let _ = unsafe { libc::sigfillset(&mut sigset as *mut libc::sigset_t) };
+ let mut sigset = mem::MaybeUninit::uninit();
+ let _ = unsafe { libc::sigfillset(sigset.as_mut_ptr()) };
- SigSet { sigset }
+ unsafe{ SigSet { sigset: sigset.assume_init() } }
}
pub fn empty() -> SigSet {
- let mut sigset: libc::sigset_t = unsafe { mem::uninitialized() };
- let _ = unsafe { libc::sigemptyset(&mut sigset as *mut libc::sigset_t) };
+ let mut sigset = mem::MaybeUninit::uninit();
+ let _ = unsafe { libc::sigemptyset(sigset.as_mut_ptr()) };
- SigSet { sigset }
+ unsafe{ SigSet { sigset: sigset.assume_init() } }
}
pub fn add(&mut self, signal: Signal) {
@@ -380,9 +380,9 @@ impl SigSet {
/// Gets the currently blocked (masked) set of signals for the calling thread.
pub fn thread_get_mask() -> Result<SigSet> {
- let mut oldmask: SigSet = unsafe { mem::uninitialized() };
- pthread_sigmask(SigmaskHow::SIG_SETMASK, None, Some(&mut oldmask))?;
- Ok(oldmask)
+ let mut oldmask = mem::MaybeUninit::uninit();
+ do_pthread_sigmask(SigmaskHow::SIG_SETMASK, None, Some(oldmask.as_mut_ptr()))?;
+ Ok(unsafe{ SigSet{sigset: oldmask.assume_init()}})
}
/// Sets the set of signals as the signal mask for the calling thread.
@@ -402,18 +402,20 @@ impl SigSet {
/// Sets the set of signals as the signal mask, and returns the old mask.
pub fn thread_swap_mask(&self, how: SigmaskHow) -> Result<SigSet> {
- let mut oldmask: SigSet = unsafe { mem::uninitialized() };
- pthread_sigmask(how, Some(self), Some(&mut oldmask))?;
- Ok(oldmask)
+ let mut oldmask = mem::MaybeUninit::uninit();
+ do_pthread_sigmask(how, Some(self), Some(oldmask.as_mut_ptr()))?;
+ Ok(unsafe{ SigSet{sigset: oldmask.assume_init()}})
}
/// Suspends execution of the calling thread until one of the signals in the
/// signal mask becomes pending, and returns the accepted signal.
pub fn wait(&self) -> Result<Signal> {
- let mut signum: libc::c_int = unsafe { mem::uninitialized() };
- let res = unsafe { libc::sigwait(&self.sigset as *const libc::sigset_t, &mut signum) };
+ let mut signum = mem::MaybeUninit::uninit();
+ let res = unsafe { libc::sigwait(&self.sigset as *const libc::sigset_t, signum.as_mut_ptr()) };
- Errno::result(res).map(|_| Signal::from_c_int(signum).unwrap())
+ Errno::result(res).map(|_| unsafe {
+ Signal::from_c_int(signum.assume_init()).unwrap()
+ })
}
}
@@ -451,20 +453,23 @@ impl SigAction {
/// is the `SigAction` variant). `mask` specifies other signals to block during execution of
/// the signal-catching function.
pub fn new(handler: SigHandler, flags: SaFlags, mask: SigSet) -> SigAction {
- let mut s = unsafe { mem::uninitialized::<libc::sigaction>() };
- s.sa_sigaction = match handler {
- SigHandler::SigDfl => libc::SIG_DFL,
- SigHandler::SigIgn => libc::SIG_IGN,
- SigHandler::Handler(f) => f as *const extern fn(libc::c_int) as usize,
- SigHandler::SigAction(f) => f as *const extern fn(libc::c_int, *mut libc::siginfo_t, *mut libc::c_void) as usize,
- };
- s.sa_flags = match handler {
- SigHandler::SigAction(_) => (flags | SaFlags::SA_SIGINFO).bits(),
- _ => (flags - SaFlags::SA_SIGINFO).bits(),
- };
- s.sa_mask = mask.sigset;
-
- SigAction { sigaction: s }
+ let mut s = mem::MaybeUninit::<libc::sigaction>::uninit();
+ unsafe {
+ let p = s.as_mut_ptr();
+ (*p).sa_sigaction = match handler {
+ SigHandler::SigDfl => libc::SIG_DFL,
+ SigHandler::SigIgn => libc::SIG_IGN,
+ SigHandler::Handler(f) => f as *const extern fn(libc::c_int) as usize,
+ SigHandler::SigAction(f) => f as *const extern fn(libc::c_int, *mut libc::siginfo_t, *mut libc::c_void) as usize,
+ };
+ (*p).sa_flags = match handler {
+ SigHandler::SigAction(_) => (flags | SaFlags::SA_SIGINFO).bits(),
+ _ => (flags - SaFlags::SA_SIGINFO).bits(),
+ };
+ (*p).sa_mask = mask.sigset;
+
+ SigAction { sigaction: s.assume_init() }
+ }
}
/// Returns the flags set on the action.
@@ -501,12 +506,13 @@ impl SigAction {
/// the body of the signal-catching function. Be certain to only make syscalls that are explicitly
/// marked safe for signal handlers and only share global data using atomics.
pub unsafe fn sigaction(signal: Signal, sigaction: &SigAction) -> Result<SigAction> {
- let mut oldact = mem::uninitialized::<libc::sigaction>();
+ let mut oldact = mem::MaybeUninit::<libc::sigaction>::uninit();
- let res =
- libc::sigaction(signal as libc::c_int, &sigaction.sigaction as *const libc::sigaction, &mut oldact as *mut libc::sigaction);
+ let res = libc::sigaction(signal as libc::c_int,
+ &sigaction.sigaction as *const libc::sigaction,
+ oldact.as_mut_ptr());
- Errno::result(res).map(|_| SigAction { sigaction: oldact })
+ Errno::result(res).map(|_| SigAction { sigaction: oldact.assume_init() })
}
/// Signal management (see [signal(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/signal.html))
@@ -582,6 +588,25 @@ pub unsafe fn signal(signal: Signal, handler: SigHandler) -> Result<SigHandler>
})
}
+fn do_pthread_sigmask(how: SigmaskHow,
+ set: Option<&SigSet>,
+ oldset: Option<*mut libc::sigset_t>) -> Result<()> {
+ if set.is_none() && oldset.is_none() {
+ return Ok(())
+ }
+
+ let res = unsafe {
+ // if set or oldset is None, pass in null pointers instead
+ libc::pthread_sigmask(how as libc::c_int,
+ set.map_or_else(ptr::null::<libc::sigset_t>,
+ |s| &s.sigset as *const libc::sigset_t),
+ oldset.unwrap_or(ptr::null_mut())
+ )
+ };
+
+ Errno::result(res).map(drop)
+}
+
/// Manages the signal mask (set of blocked signals) for the calling thread.
///
/// If the `set` parameter is `Some(..)`, then the signal mask will be updated with the signal set.
@@ -599,21 +624,9 @@ pub unsafe fn signal(signal: Signal, handler: SigHandler) -> Result<SigHandler>
/// or [`sigprocmask`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigprocmask.html) man pages.
pub fn pthread_sigmask(how: SigmaskHow,
set: Option<&SigSet>,
- oldset: Option<&mut SigSet>) -> Result<()> {
- if set.is_none() && oldset.is_none() {
- return Ok(())
- }
-
- let res = unsafe {
- // if set or oldset is None, pass in null pointers instead
- libc::pthread_sigmask(how as libc::c_int,
- set.map_or_else(ptr::null::<libc::sigset_t>,
- |s| &s.sigset as *const libc::sigset_t),
- oldset.map_or_else(ptr::null_mut::<libc::sigset_t>,
- |os| &mut os.sigset as *mut libc::sigset_t))
- };
-
- Errno::result(res).map(drop)
+ oldset: Option<&mut SigSet>) -> Result<()>
+{
+ do_pthread_sigmask(how, set, oldset.map(|os| &mut os.sigset as *mut _ ))
}
/// Examine and change blocked signals.