Skip to content

Commit

Permalink
feat: I/O safety for 'sys/signal' (#1936)
Browse files Browse the repository at this point in the history
* refactor: I/O safety for sys/signal.rs

* chore: changelog entry
  • Loading branch information
SteveLauC authored Jun 10, 2024
1 parent 8a1e9df commit 51e552a
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 11 deletions.
1 change: 1 addition & 0 deletions changelog/1936.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Module sys/signal now adopts I/O safety
1 change: 1 addition & 0 deletions changelog/1936.removed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Type `SigevNotify` is no longer `PartialEq`, `Eq` and `Hash` due to the use of `BorrowedFd`
31 changes: 20 additions & 11 deletions src/sys/signal.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
// Portions of this file are Copyright 2014 The Rust Project Developers.
// See https://www.rust-lang.org/policies/licenses.

//! Operating system signals.

use crate::errno::Errno;
Expand All @@ -10,8 +7,6 @@ use std::fmt;
use std::hash::{Hash, Hasher};
use std::mem;
use std::ops::BitOr;
#[cfg(freebsdlike)]
use std::os::unix::io::RawFd;
use std::ptr;
use std::str::FromStr;

Expand Down Expand Up @@ -1114,8 +1109,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 = "fuchsia", target_os = "hurd", 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 @@ -1131,7 +1126,7 @@ pub enum SigevNotify {
#[cfg(freebsdlike)]
SigevKevent {
/// File descriptor of the kqueue to notify.
kq: RawFd,
kq: std::os::fd::BorrowedFd<'fd>,
/// Will be contained in the kevent's `udata` field.
udata: libc::intptr_t
},
Expand All @@ -1140,7 +1135,7 @@ pub enum SigevNotify {
#[cfg(feature = "event")]
SigevKeventFlags {
/// File descriptor of the kqueue to notify.
kq: RawFd,
kq: std::os::fd::BorrowedFd<'fd>,
/// Will be contained in the kevent's `udata` field.
udata: libc::intptr_t,
/// Flags that will be set on the delivered event. See `kevent(2)`.
Expand All @@ -1161,6 +1156,14 @@ 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 DragonFlyBSD.
///
/// This variant can never be constructed due to the usage of an enum with 0
/// variants.
#[doc(hidden)]
#[cfg(not(freebsdlike))]
_Unreachable(&'fd std::convert::Infallible),
}
}

Expand Down Expand Up @@ -1337,15 +1340,19 @@ mod sigevent {
},
#[cfg(freebsdlike)]
SigevNotify::SigevKevent{kq, udata} => {
use std::os::fd::AsRawFd;

sev.sigev_notify = libc::SIGEV_KEVENT;
sev.sigev_signo = kq;
sev.sigev_signo = kq.as_raw_fd();
sev.sigev_value.sival_ptr = udata as *mut libc::c_void;
},
#[cfg(target_os = "freebsd")]
#[cfg(feature = "event")]
SigevNotify::SigevKeventFlags{kq, udata, flags} => {
use std::os::fd::AsRawFd;

sev.sigev_notify = libc::SIGEV_KEVENT;
sev.sigev_signo = kq;
sev.sigev_signo = kq.as_raw_fd();
sev.sigev_value.sival_ptr = udata as *mut libc::c_void;
sev._sigev_un._kevent_flags = flags.bits();
},
Expand All @@ -1363,6 +1370,8 @@ mod sigevent {
sev.sigev_value.sival_ptr = si_value as *mut libc::c_void;
sev.sigev_notify_thread_id = thread_id;
}
#[cfg(not(freebsdlike))]
SigevNotify::_Unreachable(_) => unreachable!("This variant could never be constructed")
}
SigEvent{sigevent: sev}
}
Expand Down

0 comments on commit 51e552a

Please sign in to comment.