Skip to content

Commit

Permalink
signalfd optional file descriptor
Browse files Browse the repository at this point in the history
s
  • Loading branch information
JonathanWoollett-Light committed Nov 21, 2022
1 parent ae34683 commit 6c4312e
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 16 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ This project adheres to [Semantic Versioning](https://semver.org/).
([#1874](https://github.com/nix-rust/nix/pull/1874))
- The `addr` argument of `sys::mman::mmap` is now of type `Option<NonZeroUsize>`.
([#1870](https://github.com/nix-rust/nix/pull/1870))
- The `fd` argument to `sys::signalfd::signalfd` is now of type `Option<impl AsFd>`.
([#1874](https://github.com/nix-rust/nix/pull/1874))

### Fixed

Expand Down
29 changes: 16 additions & 13 deletions src/sys/signalfd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ use crate::Result;
pub use libc::signalfd_siginfo as siginfo;

use std::mem;
use std::os::unix::io::{AsRawFd, RawFd};
use std::os::unix::io::{AsRawFd, RawFd, FromRawFd, OwnedFd, AsFd};
use std::mem::ManuallyDrop;

libc_bitflags! {
pub struct SfdFlags: libc::c_int {
Expand All @@ -31,10 +32,11 @@ libc_bitflags! {
}
}

pub const SIGNALFD_NEW: RawFd = -1;
#[deprecated(since = "0.23.0", note = "use mem::size_of::<siginfo>() instead")]
pub const SIGNALFD_SIGINFO_SIZE: usize = mem::size_of::<siginfo>();



/// Creates a new file descriptor for reading signals.
///
/// **Important:** please read the module level documentation about signal discarding before using
Expand All @@ -46,13 +48,14 @@ pub const SIGNALFD_SIGINFO_SIZE: usize = mem::size_of::<siginfo>();
/// signalfd (the default handler will be invoked instead).
///
/// See [the signalfd man page for more information](https://man7.org/linux/man-pages/man2/signalfd.2.html)
pub fn signalfd(fd: RawFd, mask: &SigSet, flags: SfdFlags) -> Result<RawFd> {
pub fn signalfd(fd: Option<impl AsFd>, mask: &SigSet, flags: SfdFlags) -> Result<OwnedFd> {
let raw_fd = fd.map_or(-1, |x|x.as_fd().as_raw_fd());
unsafe {
Errno::result(libc::signalfd(
fd as libc::c_int,
raw_fd,
mask.as_ref(),
flags.bits(),
))
)).map(|raw_fd|FromRawFd::from_raw_fd(raw_fd))
}
}

Expand Down Expand Up @@ -82,30 +85,30 @@ pub fn signalfd(fd: RawFd, mask: &SigSet, flags: SfdFlags) -> Result<RawFd> {
/// Err(err) => (), // some error happend
/// }
/// ```
#[derive(Debug, Eq, Hash, PartialEq)]
pub struct SignalFd(RawFd);
#[derive(Debug)]
pub struct SignalFd(ManuallyDrop<OwnedFd>);

impl SignalFd {
pub fn new(mask: &SigSet) -> Result<SignalFd> {
Self::with_flags(mask, SfdFlags::empty())
}

pub fn with_flags(mask: &SigSet, flags: SfdFlags) -> Result<SignalFd> {
let fd = signalfd(SIGNALFD_NEW, mask, flags)?;
let fd = signalfd(None::<OwnedFd>, mask, flags)?;

Ok(SignalFd(fd))
Ok(SignalFd(ManuallyDrop::new(fd)))
}

pub fn set_mask(&mut self, mask: &SigSet) -> Result<()> {
signalfd(self.0, mask, SfdFlags::empty()).map(drop)
signalfd(Some(self.0.as_fd()), mask, SfdFlags::empty()).map(drop)
}

pub fn read_signal(&mut self) -> Result<Option<siginfo>> {
let mut buffer = mem::MaybeUninit::<siginfo>::uninit();

let size = mem::size_of_val(&buffer);
let res = Errno::result(unsafe {
libc::read(self.0, buffer.as_mut_ptr() as *mut libc::c_void, size)
libc::read(self.0.as_raw_fd(), buffer.as_mut_ptr() as *mut libc::c_void, size)
})
.map(|r| r as usize);
match res {
Expand All @@ -119,7 +122,7 @@ impl SignalFd {

impl Drop for SignalFd {
fn drop(&mut self) {
let e = unistd::close(self.0);
let e = unistd::close(self.0.as_raw_fd());
if !std::thread::panicking() && e == Err(Errno::EBADF) {
panic!("Closing an invalid file descriptor!");
};
Expand All @@ -128,7 +131,7 @@ impl Drop for SignalFd {

impl AsRawFd for SignalFd {
fn as_raw_fd(&self) -> RawFd {
self.0
self.0.as_raw_fd()
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/unistd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use std::ffi::{CString, OsStr};
#[cfg(not(target_os = "redox"))]
use std::os::unix::ffi::OsStrExt;
use std::os::unix::ffi::OsStringExt;
use std::os::unix::io::RawFd;
use std::os::unix::io::{IntoRawFd, RawFd};
use std::path::PathBuf;
use std::{fmt, mem, ptr};

Expand Down Expand Up @@ -1060,8 +1060,8 @@ pub fn gethostname() -> Result<OsString> {
/// let f = tempfile::tempfile().unwrap();
/// close(f.into_raw_fd()).unwrap(); // Good. into_raw_fd consumes f
/// ```
pub fn close(fd: RawFd) -> Result<()> {
let res = unsafe { libc::close(fd) };
pub fn close<F: IntoRawFd>(fd: F) -> Result<()> {
let res = unsafe { libc::close(fd.into_raw_fd()) };
Errno::result(res).map(drop)
}

Expand Down

0 comments on commit 6c4312e

Please sign in to comment.