1 | use std::{ |
2 | fs, io, |
3 | os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}, |
4 | }; |
5 | |
6 | /// If the `calloop` cargo feature is enabled, this can be used |
7 | /// as an `EventSource` in a calloop event loop. |
8 | #[must_use ] |
9 | #[derive (Debug)] |
10 | pub struct ReadPipe { |
11 | #[cfg (feature = "calloop" )] |
12 | file: calloop::generic::Generic<fs::File>, |
13 | #[cfg (not(feature = "calloop" ))] |
14 | file: fs::File, |
15 | } |
16 | |
17 | #[cfg (feature = "calloop" )] |
18 | impl io::Read for ReadPipe { |
19 | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
20 | unsafe { self.file.get_mut().read(buf) } |
21 | } |
22 | } |
23 | |
24 | #[cfg (not(feature = "calloop" ))] |
25 | impl io::Read for ReadPipe { |
26 | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
27 | self.file.read(buf) |
28 | } |
29 | } |
30 | |
31 | #[cfg (feature = "calloop" )] |
32 | impl FromRawFd for ReadPipe { |
33 | unsafe fn from_raw_fd(fd: RawFd) -> ReadPipe { |
34 | ReadPipe { |
35 | file: calloop::generic::Generic::new( |
36 | file:unsafe { FromRawFd::from_raw_fd(fd) }, |
37 | interest:calloop::Interest::READ, |
38 | calloop::Mode::Level, |
39 | ), |
40 | } |
41 | } |
42 | } |
43 | |
44 | #[cfg (feature = "calloop" )] |
45 | impl From<OwnedFd> for ReadPipe { |
46 | fn from(owned: OwnedFd) -> Self { |
47 | ReadPipe { |
48 | file: calloop::generic::Generic::new( |
49 | file:owned.into(), |
50 | interest:calloop::Interest::READ, |
51 | calloop::Mode::Level, |
52 | ), |
53 | } |
54 | } |
55 | } |
56 | |
57 | #[cfg (not(feature = "calloop" ))] |
58 | impl FromRawFd for ReadPipe { |
59 | unsafe fn from_raw_fd(fd: RawFd) -> ReadPipe { |
60 | ReadPipe { file: unsafe { FromRawFd::from_raw_fd(fd) } } |
61 | } |
62 | } |
63 | |
64 | #[cfg (not(feature = "calloop" ))] |
65 | impl From<OwnedFd> for ReadPipe { |
66 | fn from(owned: OwnedFd) -> Self { |
67 | ReadPipe { file: owned.into() } |
68 | } |
69 | } |
70 | |
71 | #[cfg (feature = "calloop" )] |
72 | impl AsRawFd for ReadPipe { |
73 | fn as_raw_fd(&self) -> RawFd { |
74 | self.file.get_ref().as_raw_fd() |
75 | } |
76 | } |
77 | |
78 | #[cfg (feature = "calloop" )] |
79 | impl AsFd for ReadPipe { |
80 | fn as_fd(&self) -> BorrowedFd<'_> { |
81 | self.file.get_ref().as_fd() |
82 | } |
83 | } |
84 | |
85 | #[cfg (not(feature = "calloop" ))] |
86 | impl AsRawFd for ReadPipe { |
87 | fn as_raw_fd(&self) -> RawFd { |
88 | self.file.as_raw_fd() |
89 | } |
90 | } |
91 | #[cfg (not(feature = "calloop" ))] |
92 | |
93 | impl AsFd for ReadPipe { |
94 | fn as_fd(&self) -> BorrowedFd<'_> { |
95 | self.file.as_fd() |
96 | } |
97 | } |
98 | |
99 | #[cfg (feature = "calloop" )] |
100 | impl IntoRawFd for ReadPipe { |
101 | fn into_raw_fd(self) -> RawFd { |
102 | self.file.unwrap().as_raw_fd() |
103 | } |
104 | } |
105 | |
106 | #[cfg (feature = "calloop" )] |
107 | impl From<ReadPipe> for OwnedFd { |
108 | fn from(read_pipe: ReadPipe) -> Self { |
109 | read_pipe.file.unwrap().into() |
110 | } |
111 | } |
112 | |
113 | #[cfg (not(feature = "calloop" ))] |
114 | impl IntoRawFd for ReadPipe { |
115 | fn into_raw_fd(self) -> RawFd { |
116 | self.file.into_raw_fd() |
117 | } |
118 | } |
119 | |
120 | #[cfg (not(feature = "calloop" ))] |
121 | impl From<ReadPipe> for OwnedFd { |
122 | fn from(read_pipe: ReadPipe) -> Self { |
123 | read_pipe.file.into() |
124 | } |
125 | } |
126 | |
127 | #[cfg (feature = "calloop" )] |
128 | impl calloop::EventSource for ReadPipe { |
129 | type Event = (); |
130 | type Error = std::io::Error; |
131 | type Metadata = calloop::generic::NoIoDrop<fs::File>; |
132 | type Ret = calloop::PostAction; |
133 | |
134 | fn process_events<F>( |
135 | &mut self, |
136 | readiness: calloop::Readiness, |
137 | token: calloop::Token, |
138 | mut callback: F, |
139 | ) -> std::io::Result<calloop::PostAction> |
140 | where |
141 | F: FnMut((), &mut calloop::generic::NoIoDrop<fs::File>) -> Self::Ret, |
142 | { |
143 | self.file.process_events(readiness, token, |_, file| Ok(callback((), file))) |
144 | } |
145 | |
146 | fn register( |
147 | &mut self, |
148 | poll: &mut calloop::Poll, |
149 | token_factory: &mut calloop::TokenFactory, |
150 | ) -> calloop::Result<()> { |
151 | self.file.register(poll, token_factory) |
152 | } |
153 | |
154 | fn reregister( |
155 | &mut self, |
156 | poll: &mut calloop::Poll, |
157 | token_factory: &mut calloop::TokenFactory, |
158 | ) -> calloop::Result<()> { |
159 | self.file.reregister(poll, token_factory) |
160 | } |
161 | |
162 | fn unregister(&mut self, poll: &mut calloop::Poll) -> calloop::Result<()> { |
163 | self.file.unregister(poll) |
164 | } |
165 | } |
166 | |