Skip to content

Commit 99e8173

Browse files
signalfd optional file descriptor
1 parent 4c52102 commit 99e8173

File tree

3 files changed

+21
-16
lines changed

3 files changed

+21
-16
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ This project adheres to [Semantic Versioning](https://semver.org/).
4747
([#1870](https://github.com/nix-rust/nix/pull/1870))
4848
- The `length` argument of `sys::mman::mmap` is now of type `NonZeroUsize`.
4949
([#1873](https://github.com/nix-rust/nix/pull/1873))
50+
- The `fd` argument to `sys::signalfd::signalfd` is now of type `Option<impl AsFd>`.
51+
([#1874](https://github.com/nix-rust/nix/pull/1874))
5052

5153
### Fixed
5254

src/sys/signalfd.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ use crate::Result;
2222
pub use libc::signalfd_siginfo as siginfo;
2323

2424
use std::mem;
25-
use std::os::unix::io::{AsRawFd, RawFd};
25+
use std::os::unix::io::{AsRawFd, RawFd, FromRawFd, OwnedFd, AsFd};
26+
use std::mem::ManuallyDrop;
2627

2728
libc_bitflags! {
2829
pub struct SfdFlags: libc::c_int {
@@ -31,10 +32,11 @@ libc_bitflags! {
3132
}
3233
}
3334

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

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

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

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

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

96-
Ok(SignalFd(fd))
99+
Ok(SignalFd(ManuallyDrop::new(fd)))
97100
}
98101

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

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

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

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

129132
impl AsRawFd for SignalFd {
130133
fn as_raw_fd(&self) -> RawFd {
131-
self.0
134+
self.0.as_raw_fd()
132135
}
133136
}
134137

src/unistd.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use std::ffi::{CString, OsStr};
3434
#[cfg(not(target_os = "redox"))]
3535
use std::os::unix::ffi::OsStrExt;
3636
use std::os::unix::ffi::OsStringExt;
37-
use std::os::unix::io::RawFd;
37+
use std::os::unix::io::{IntoRawFd, RawFd};
3838
use std::path::PathBuf;
3939
use std::{fmt, mem, ptr};
4040

@@ -1060,8 +1060,8 @@ pub fn gethostname() -> Result<OsString> {
10601060
/// let f = tempfile::tempfile().unwrap();
10611061
/// close(f.into_raw_fd()).unwrap(); // Good. into_raw_fd consumes f
10621062
/// ```
1063-
pub fn close(fd: RawFd) -> Result<()> {
1064-
let res = unsafe { libc::close(fd) };
1063+
pub fn close<F: IntoRawFd>(fd: F) -> Result<()> {
1064+
let res = unsafe { libc::close(fd.into_raw_fd()) };
10651065
Errno::result(res).map(drop)
10661066
}
10671067

0 commit comments

Comments
 (0)