@@ -22,7 +22,8 @@ use crate::Result;
22
22
pub use libc:: signalfd_siginfo as siginfo;
23
23
24
24
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 ;
26
27
27
28
libc_bitflags ! {
28
29
pub struct SfdFlags : libc:: c_int {
@@ -31,10 +32,11 @@ libc_bitflags! {
31
32
}
32
33
}
33
34
34
- pub const SIGNALFD_NEW : RawFd = -1 ;
35
35
#[ deprecated( since = "0.23.0" , note = "use mem::size_of::<siginfo>() instead" ) ]
36
36
pub const SIGNALFD_SIGINFO_SIZE : usize = mem:: size_of :: < siginfo > ( ) ;
37
37
38
+
39
+
38
40
/// Creates a new file descriptor for reading signals.
39
41
///
40
42
/// **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>();
46
48
/// signalfd (the default handler will be invoked instead).
47
49
///
48
50
/// 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 ( ) ) ;
50
53
unsafe {
51
54
Errno :: result ( libc:: signalfd (
52
- fd as libc :: c_int ,
55
+ raw_fd ,
53
56
mask. as_ref ( ) ,
54
57
flags. bits ( ) ,
55
- ) )
58
+ ) ) . map ( |raw_fd| FromRawFd :: from_raw_fd ( raw_fd ) )
56
59
}
57
60
}
58
61
@@ -82,30 +85,30 @@ pub fn signalfd(fd: RawFd, mask: &SigSet, flags: SfdFlags) -> Result<RawFd> {
82
85
/// Err(err) => (), // some error happend
83
86
/// }
84
87
/// ```
85
- #[ derive( Debug , Eq , Hash , PartialEq ) ]
86
- pub struct SignalFd ( RawFd ) ;
88
+ #[ derive( Debug ) ]
89
+ pub struct SignalFd ( ManuallyDrop < OwnedFd > ) ;
87
90
88
91
impl SignalFd {
89
92
pub fn new ( mask : & SigSet ) -> Result < SignalFd > {
90
93
Self :: with_flags ( mask, SfdFlags :: empty ( ) )
91
94
}
92
95
93
96
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) ?;
95
98
96
- Ok ( SignalFd ( fd ) )
99
+ Ok ( SignalFd ( ManuallyDrop :: new ( fd ) ) )
97
100
}
98
101
99
102
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)
101
104
}
102
105
103
106
pub fn read_signal ( & mut self ) -> Result < Option < siginfo > > {
104
107
let mut buffer = mem:: MaybeUninit :: < siginfo > :: uninit ( ) ;
105
108
106
109
let size = mem:: size_of_val ( & buffer) ;
107
110
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)
109
112
} )
110
113
. map ( |r| r as usize ) ;
111
114
match res {
@@ -119,7 +122,7 @@ impl SignalFd {
119
122
120
123
impl Drop for SignalFd {
121
124
fn drop ( & mut self ) {
122
- let e = unistd:: close ( self . 0 ) ;
125
+ let e = unistd:: close ( self . 0 . as_raw_fd ( ) ) ;
123
126
if !std:: thread:: panicking ( ) && e == Err ( Errno :: EBADF ) {
124
127
panic ! ( "Closing an invalid file descriptor!" ) ;
125
128
} ;
@@ -128,7 +131,7 @@ impl Drop for SignalFd {
128
131
129
132
impl AsRawFd for SignalFd {
130
133
fn as_raw_fd ( & self ) -> RawFd {
131
- self . 0
134
+ self . 0 . as_raw_fd ( )
132
135
}
133
136
}
134
137
0 commit comments