@@ -22,7 +22,8 @@ use crate::Result;
2222pub use libc:: signalfd_siginfo as siginfo;
2323
2424use 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
2728libc_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" ) ]
3636pub 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
8891impl 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
120123impl 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
129132impl AsRawFd for SignalFd {
130133 fn as_raw_fd ( & self ) -> RawFd {
131- self . 0
134+ self . 0 . as_raw_fd ( )
132135 }
133136}
134137
0 commit comments