Skip to content

Commit

Permalink
feat: I/O safety for 'sys/signal'
Browse files Browse the repository at this point in the history
  • Loading branch information
SteveLauC committed Dec 11, 2022
1 parent 3d3e6b9 commit 9a3760c
Showing 1 changed file with 14 additions and 6 deletions.
20 changes: 14 additions & 6 deletions src/sys/signal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use cfg_if::cfg_if;
use std::fmt;
use std::mem;
#[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
use std::os::unix::io::RawFd;
use std::os::unix::io::BorrowedFd;
use std::ptr;
use std::str::FromStr;

Expand Down Expand Up @@ -980,8 +980,8 @@ pub type type_of_thread_id = libc::pid_t;
// as a pointer, because neither libc nor the kernel ever dereference it. nix
// therefore presents it as an intptr_t, which is how kevent uses it.
#[cfg(not(any(target_os = "openbsd", target_os = "redox")))]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum SigevNotify {
#[derive(Clone, Copy, Debug)]
pub enum SigevNotify <'fd> {
/// No notification will be delivered
SigevNone,
/// Notify by delivering a signal to the process.
Expand All @@ -999,7 +999,7 @@ pub enum SigevNotify {
#[cfg_attr(docsrs, doc(cfg(all())))]
SigevKevent {
/// File descriptor of the kqueue to notify.
kq: RawFd,
kq: BorrowedFd<'fd>,
/// Will be contained in the kevent's `udata` field.
udata: libc::intptr_t
},
Expand All @@ -1015,6 +1015,10 @@ pub enum SigevNotify {
/// structure of the queued signal.
si_value: libc::intptr_t
},
/// A helper variant to resolve the unused parameter (`'fd`) problem on platforms
/// other than FreeBSD and DragonFly.
#[doc(hidden)]
_Unreachable(std::marker::PhantomData<&'fd std::convert::Infallible>),
}
}

Expand All @@ -1029,6 +1033,8 @@ mod sigevent {
use super::SigevNotify;
#[cfg(any(target_os = "freebsd", target_os = "linux"))]
use super::type_of_thread_id;
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
use std::os::unix::io::AsRawFd;

/// Used to request asynchronous notification of the completion of certain
/// events, such as POSIX AIO and timers.
Expand Down Expand Up @@ -1069,12 +1075,13 @@ mod sigevent {
#[cfg(all(target_os = "linux", target_env = "uclibc"))]
SigevNotify::SigevThreadId{..} => libc::SIGEV_THREAD_ID,
#[cfg(any(all(target_os = "linux", target_env = "musl"), target_arch = "mips"))]
SigevNotify::SigevThreadId{..} => 4 // No SIGEV_THREAD_ID defined
SigevNotify::SigevThreadId{..} => 4, // No SIGEV_THREAD_ID defined
SigevNotify::_Unreachable(_) => unreachable!("This variant could never be constructed")
};
sev.sigev_signo = match sigev_notify {
SigevNotify::SigevSignal{ signal, .. } => signal as libc::c_int,
#[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
SigevNotify::SigevKevent{ kq, ..} => kq,
SigevNotify::SigevKevent{ kq, ..} => kq.as_raw_fd(),
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
SigevNotify::SigevThreadId{ signal, .. } => signal as libc::c_int,
_ => 0
Expand All @@ -1086,6 +1093,7 @@ mod sigevent {
SigevNotify::SigevKevent{ udata, .. } => udata as *mut libc::c_void,
#[cfg(any(target_os = "freebsd", target_os = "linux"))]
SigevNotify::SigevThreadId{ si_value, .. } => si_value as *mut libc::c_void,
SigevNotify::_Unreachable(_) => unreachable!("This variant could never be constructed")
};
SigEvent::set_tid(&mut sev, &sigev_notify);
SigEvent{sigevent: sev}
Expand Down

0 comments on commit 9a3760c

Please sign in to comment.