Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove nix from the public API #182

Merged
merged 2 commits into from
May 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## Unreleased

#### Breaking Changes

- Remove `nix` from the public API. This replaces `Signal` with a home-grown
`Signal` enum and `siginfo` with a structure that provides most of its fields.

## 0.13.0 -- 2024-02-25

#### Breaking changes
Expand Down
161 changes: 149 additions & 12 deletions src/sources/signals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,165 @@ use std::io::Error as IoError;
use std::os::raw::c_int;

use nix::sys::signal::SigSet;
pub use nix::sys::signal::Signal;
pub use nix::sys::signalfd::siginfo;
use nix::sys::signalfd::{SfdFlags, SignalFd};
use nix::sys::signalfd::{siginfo, SfdFlags, SignalFd};

use super::generic::{FdWrapper, Generic};
use crate::{EventSource, Interest, Mode, Poll, PostAction, Readiness, Token, TokenFactory};

// Code taken from async-signal
macro_rules! define_signal_enum {
(
$(#[$outer:meta])*
pub enum Signal {
$(
$(#[$inner:meta])*
$value:ident,
)*
}
) => {
$(#[$outer])*
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
#[repr(i32)]
pub enum Signal {
$(
$(#[$inner])*
$value = nix::sys::signal::Signal::$value as i32,
)*
}

impl Signal {
/// Returns the signal number.
fn as_nix(self) -> nix::sys::signal::Signal {
match self {
$(
Signal::$value => nix::sys::signal::Signal::$value,
)*
}
}

/// Generate from a signal number.
fn from_num(id: i32) -> Self {
match nix::sys::signal::Signal::try_from(id) {
$(
Ok(nix::sys::signal::Signal::$value) => Self::$value,
)*

Ok(sig) => panic!("unknown signal: {:?}", sig),
Err(_) => panic!("unknown signal: {}", id)
}
}
}
}
}

define_signal_enum! {
// Copied from https://github.com/bytecodealliance/rustix/blob/main/src/backend/linux_raw/process/types.rs#L81-L161

/// The signal types that we are able to listen for.
pub enum Signal {
/// `SIGHUP`
SIGHUP,
/// `SIGINT`
SIGINT,
/// `SIGQUIT`
SIGQUIT,
/// `SIGILL`
SIGILL,
/// `SIGTRAP`
SIGTRAP,
/// `SIGABRT`, aka `SIGIOT`
#[doc(alias = "Iot")]
#[doc(alias = "Abrt")]
SIGABRT,
/// `SIGBUS`
SIGBUS,
/// `SIGFPE`
SIGFPE,
/// `SIGKILL`
SIGKILL,
/// `SIGUSR1`
SIGUSR1,
/// `SIGSEGV`
SIGSEGV,
/// `SIGUSR2`
SIGUSR2,
/// `SIGPIPE`
SIGPIPE,
/// `SIGALRM`
#[doc(alias = "Alrm")]
SIGALRM,
/// `SIGTERM`
SIGTERM,
/// `SIGCHLD`
#[doc(alias = "Chld")]
SIGCHLD,
/// `SIGCONT`
SIGCONT,
/// `SIGSTOP`
SIGSTOP,
/// `SIGTSTP`
SIGTSTP,
/// `SIGTTIN`
SIGTTIN,
/// `SIGTTOU`
SIGTTOU,
/// `SIGURG`
SIGURG,
/// `SIGXCPU`
SIGXCPU,
/// `SIGXFSZ`
SIGXFSZ,
/// `SIGVTALRM`
#[doc(alias = "Vtalrm")]
SIGVTALRM,
/// `SIGPROF`
SIGPROF,
/// `SIGWINCH`
SIGWINCH,
/// `SIGIO`, aka `SIGPOLL`
#[doc(alias = "Poll")]
SIGIO,
/// `SIGSYS`, aka `SIGUNUSED`
#[doc(alias = "Unused")]
SIGSYS,
}
}

/// An event generated by the signal event source
#[derive(Copy, Clone, Debug)]
pub struct Event {
info: siginfo,
}

macro_rules! inner_accessors {
($($name:ident => $sname:ident: $ty:ty),*) => {$(
/// Gets the `
#[doc = stringify!($sname)]
/// ` field.
pub fn $name(&self) -> $ty {
use core::convert::TryInto;
self.info.$sname.try_into().unwrap()
}
)*}
}

impl Event {
/// Retrieve the signal number that was receive
pub fn signal(&self) -> Signal {
Signal::try_from(self.info.ssi_signo as c_int).unwrap()
Signal::from_num(self.info.ssi_signo as c_int)
}

/// Access the full `siginfo_t` associated with this signal event
pub fn full_info(&self) -> siginfo {
self.info
inner_accessors! {
errno => ssi_errno: i32,
code => ssi_code: i32,
pid => ssi_pid: u32,
uid => ssi_uid: u32,
fd => ssi_fd: i32,
tid => ssi_tid: u32,
bad => ssi_band: u32,
overrun => ssi_overrun: u32,
trapno => ssi_trapno: u32,
status => ssi_status: u32
}
}

Expand All @@ -52,7 +189,7 @@ impl Signals {
pub fn new(signals: &[Signal]) -> crate::Result<Signals> {
let mut mask = SigSet::empty();
for &s in signals {
mask.add(s);
mask.add(s.as_nix());
}

// Mask the signals for this thread
Expand All @@ -73,7 +210,7 @@ impl Signals {
/// have still been changed.
pub fn add_signals(&mut self, signals: &[Signal]) -> crate::Result<()> {
for &s in signals {
self.mask.add(s);
self.mask.add(s.as_nix());
}
self.mask.thread_block().map_err(IoError::from)?;

Expand All @@ -94,8 +231,8 @@ impl Signals {
pub fn remove_signals(&mut self, signals: &[Signal]) -> crate::Result<()> {
let mut removed = SigSet::empty();
for &s in signals {
self.mask.remove(s);
removed.add(s);
self.mask.remove(s.as_nix());
removed.add(s.as_nix());
}
removed.thread_unblock().map_err(IoError::from)?;

Expand All @@ -116,7 +253,7 @@ impl Signals {
pub fn set_signals(&mut self, signals: &[Signal]) -> crate::Result<()> {
let mut new_mask = SigSet::empty();
for &s in signals {
new_mask.add(s);
new_mask.add(s.as_nix());
}

self.mask.thread_unblock().map_err(IoError::from)?;
Expand Down
8 changes: 4 additions & 4 deletions tests/signals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ mod test {
.unwrap();

// send ourselves a SIGUSR1
kill(Pid::this(), Signal::SIGUSR1).unwrap();
kill(Pid::this(), nix::sys::signal::Signal::SIGUSR1).unwrap();

event_loop
.dispatch(Some(Duration::from_millis(10)), &mut signal_received)
Expand Down Expand Up @@ -79,7 +79,7 @@ mod test {
.unwrap();

// send ourselves a SIGUSR2
kill(Pid::this(), Signal::SIGUSR2).unwrap();
kill(Pid::this(), nix::sys::signal::Signal::SIGUSR2).unwrap();

event_loop
.dispatch(Some(Duration::from_millis(10)), &mut signal_received)
Expand Down Expand Up @@ -110,11 +110,11 @@ mod test {

// block sigusr2 anyway, to not be killed by it
let mut set = SigSet::empty();
set.add(Signal::SIGUSR2);
set.add(nix::sys::signal::Signal::SIGUSR2);
set.thread_block().unwrap();

// send ourselves a SIGUSR2
kill(Pid::this(), Signal::SIGUSR2).unwrap();
kill(Pid::this(), nix::sys::signal::Signal::SIGUSR2).unwrap();

event_loop
.dispatch(Some(Duration::from_millis(10)), &mut signal_received)
Expand Down
Loading