From 6c4312e125e263372a7762271181a9f01fb12e38 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Mon, 21 Nov 2022 00:35:20 +0000 Subject: [PATCH] signalfd optional file descriptor s --- CHANGELOG.md | 2 ++ src/sys/signalfd.rs | 29 ++++++++++++++++------------- src/unistd.rs | 6 +++--- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d634c378d0..1ebe419477 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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`. ([#1870](https://github.com/nix-rust/nix/pull/1870)) +- The `fd` argument to `sys::signalfd::signalfd` is now of type `Option`. + ([#1874](https://github.com/nix-rust/nix/pull/1874)) ### Fixed diff --git a/src/sys/signalfd.rs b/src/sys/signalfd.rs index 095e590850..715e6545a1 100644 --- a/src/sys/signalfd.rs +++ b/src/sys/signalfd.rs @@ -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 { @@ -31,10 +32,11 @@ libc_bitflags! { } } -pub const SIGNALFD_NEW: RawFd = -1; #[deprecated(since = "0.23.0", note = "use mem::size_of::() instead")] pub const SIGNALFD_SIGINFO_SIZE: usize = mem::size_of::(); + + /// Creates a new file descriptor for reading signals. /// /// **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::(); /// 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 { +pub fn signalfd(fd: Option, mask: &SigSet, flags: SfdFlags) -> Result { + 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)) } } @@ -82,8 +85,8 @@ pub fn signalfd(fd: RawFd, mask: &SigSet, flags: SfdFlags) -> Result { /// Err(err) => (), // some error happend /// } /// ``` -#[derive(Debug, Eq, Hash, PartialEq)] -pub struct SignalFd(RawFd); +#[derive(Debug)] +pub struct SignalFd(ManuallyDrop); impl SignalFd { pub fn new(mask: &SigSet) -> Result { @@ -91,13 +94,13 @@ impl SignalFd { } pub fn with_flags(mask: &SigSet, flags: SfdFlags) -> Result { - let fd = signalfd(SIGNALFD_NEW, mask, flags)?; + let fd = signalfd(None::, 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> { @@ -105,7 +108,7 @@ impl SignalFd { 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 { @@ -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!"); }; @@ -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() } } diff --git a/src/unistd.rs b/src/unistd.rs index ca07b34a2e..eb70567849 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -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}; @@ -1060,8 +1060,8 @@ pub fn gethostname() -> Result { /// 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(fd: F) -> Result<()> { + let res = unsafe { libc::close(fd.into_raw_fd()) }; Errno::result(res).map(drop) }