Skip to content

Commit 0ddc42f

Browse files
committed
feat: I/O safety for 'sys/signal'
1 parent 3d3e6b9 commit 0ddc42f

File tree

1 file changed

+13
-6
lines changed

1 file changed

+13
-6
lines changed

src/sys/signal.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use cfg_if::cfg_if;
99
use std::fmt;
1010
use std::mem;
1111
#[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
12-
use std::os::unix::io::RawFd;
12+
use std::os::unix::io::BorrowedFd;
1313
use std::ptr;
1414
use std::str::FromStr;
1515

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

@@ -1029,6 +1032,8 @@ mod sigevent {
10291032
use super::SigevNotify;
10301033
#[cfg(any(target_os = "freebsd", target_os = "linux"))]
10311034
use super::type_of_thread_id;
1035+
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
1036+
use std::os::unix::io::AsRawFd;
10321037

10331038
/// Used to request asynchronous notification of the completion of certain
10341039
/// events, such as POSIX AIO and timers.
@@ -1069,12 +1074,13 @@ mod sigevent {
10691074
#[cfg(all(target_os = "linux", target_env = "uclibc"))]
10701075
SigevNotify::SigevThreadId{..} => libc::SIGEV_THREAD_ID,
10711076
#[cfg(any(all(target_os = "linux", target_env = "musl"), target_arch = "mips"))]
1072-
SigevNotify::SigevThreadId{..} => 4 // No SIGEV_THREAD_ID defined
1077+
SigevNotify::SigevThreadId{..} => 4, // No SIGEV_THREAD_ID defined
1078+
SigevNotify::_Unreachable(_) => unreachable!("This variant could never be constructed")
10731079
};
10741080
sev.sigev_signo = match sigev_notify {
10751081
SigevNotify::SigevSignal{ signal, .. } => signal as libc::c_int,
10761082
#[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
1077-
SigevNotify::SigevKevent{ kq, ..} => kq,
1083+
SigevNotify::SigevKevent{ kq, ..} => kq.as_raw_fd(),
10781084
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
10791085
SigevNotify::SigevThreadId{ signal, .. } => signal as libc::c_int,
10801086
_ => 0
@@ -1086,6 +1092,7 @@ mod sigevent {
10861092
SigevNotify::SigevKevent{ udata, .. } => udata as *mut libc::c_void,
10871093
#[cfg(any(target_os = "freebsd", target_os = "linux"))]
10881094
SigevNotify::SigevThreadId{ si_value, .. } => si_value as *mut libc::c_void,
1095+
SigevNotify::_Unreachable(_) => unreachable!("This variant could never be constructed")
10891096
};
10901097
SigEvent::set_tid(&mut sev, &sigev_notify);
10911098
SigEvent{sigevent: sev}

0 commit comments

Comments
 (0)