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 WritePipe { |
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::Write for WritePipe { |
19 | fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
20 | unsafe { self.file.get_mut().write(buf) } |
21 | } |
22 | |
23 | fn flush(&mut self) -> io::Result<()> { |
24 | unsafe { self.file.get_mut().flush() } |
25 | } |
26 | } |
27 | |
28 | #[cfg (not(feature = "calloop" ))] |
29 | impl io::Write for WritePipe { |
30 | fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
31 | self.file.write(buf) |
32 | } |
33 | |
34 | fn flush(&mut self) -> io::Result<()> { |
35 | self.file.flush() |
36 | } |
37 | } |
38 | |
39 | #[cfg (feature = "calloop" )] |
40 | impl FromRawFd for WritePipe { |
41 | unsafe fn from_raw_fd(fd: RawFd) -> WritePipe { |
42 | WritePipe { |
43 | file: calloop::generic::Generic::new( |
44 | file:unsafe { FromRawFd::from_raw_fd(fd) }, |
45 | interest:calloop::Interest::WRITE, |
46 | calloop::Mode::Level, |
47 | ), |
48 | } |
49 | } |
50 | } |
51 | |
52 | #[cfg (feature = "calloop" )] |
53 | impl From<OwnedFd> for WritePipe { |
54 | fn from(owned: OwnedFd) -> Self { |
55 | WritePipe { |
56 | file: calloop::generic::Generic::new( |
57 | file:owned.into(), |
58 | interest:calloop::Interest::WRITE, |
59 | calloop::Mode::Level, |
60 | ), |
61 | } |
62 | } |
63 | } |
64 | |
65 | #[cfg (not(feature = "calloop" ))] |
66 | impl FromRawFd for WritePipe { |
67 | unsafe fn from_raw_fd(fd: RawFd) -> WritePipe { |
68 | WritePipe { file: unsafe { FromRawFd::from_raw_fd(fd) } } |
69 | } |
70 | } |
71 | |
72 | #[cfg (not(feature = "calloop" ))] |
73 | impl From<OwnedFd> for WritePipe { |
74 | fn from(owned: OwnedFd) -> Self { |
75 | WritePipe { file: owned.into() } |
76 | } |
77 | } |
78 | |
79 | #[cfg (feature = "calloop" )] |
80 | impl AsRawFd for WritePipe { |
81 | fn as_raw_fd(&self) -> RawFd { |
82 | self.file.get_ref().as_raw_fd() |
83 | } |
84 | } |
85 | |
86 | #[cfg (feature = "calloop" )] |
87 | impl AsFd for WritePipe { |
88 | fn as_fd(&self) -> BorrowedFd { |
89 | self.file.get_ref().as_fd() |
90 | } |
91 | } |
92 | |
93 | #[cfg (not(feature = "calloop" ))] |
94 | impl AsRawFd for WritePipe { |
95 | fn as_raw_fd(&self) -> RawFd { |
96 | self.file.as_raw_fd() |
97 | } |
98 | } |
99 | #[cfg (not(feature = "calloop" ))] |
100 | |
101 | impl AsFd for WritePipe { |
102 | fn as_fd(&self) -> BorrowedFd<'_> { |
103 | self.file.as_fd() |
104 | } |
105 | } |
106 | |
107 | #[cfg (feature = "calloop" )] |
108 | impl IntoRawFd for WritePipe { |
109 | fn into_raw_fd(self) -> RawFd { |
110 | self.file.unwrap().into_raw_fd() |
111 | } |
112 | } |
113 | |
114 | #[cfg (feature = "calloop" )] |
115 | impl From<WritePipe> for OwnedFd { |
116 | fn from(write_pipe: WritePipe) -> Self { |
117 | write_pipe.file.unwrap().into() |
118 | } |
119 | } |
120 | |
121 | #[cfg (not(feature = "calloop" ))] |
122 | impl IntoRawFd for WritePipe { |
123 | fn into_raw_fd(self) -> RawFd { |
124 | self.file.into_raw_fd() |
125 | } |
126 | } |
127 | |
128 | #[cfg (not(feature = "calloop" ))] |
129 | impl From<WritePipe> for OwnedFd { |
130 | fn from(write_pipe: WritePipe) -> Self { |
131 | write_pipe.file.into() |
132 | } |
133 | } |
134 | |
135 | #[cfg (feature = "calloop" )] |
136 | impl calloop::EventSource for WritePipe { |
137 | type Event = (); |
138 | type Error = std::io::Error; |
139 | type Metadata = calloop::generic::NoIoDrop<fs::File>; |
140 | type Ret = calloop::PostAction; |
141 | |
142 | fn process_events<F>( |
143 | &mut self, |
144 | readiness: calloop::Readiness, |
145 | token: calloop::Token, |
146 | mut callback: F, |
147 | ) -> std::io::Result<calloop::PostAction> |
148 | where |
149 | F: FnMut((), &mut calloop::generic::NoIoDrop<fs::File>) -> Self::Ret, |
150 | { |
151 | self.file.process_events(readiness, token, |_, file| Ok(callback((), file))) |
152 | } |
153 | |
154 | fn register( |
155 | &mut self, |
156 | poll: &mut calloop::Poll, |
157 | token_factory: &mut calloop::TokenFactory, |
158 | ) -> calloop::Result<()> { |
159 | self.file.register(poll, token_factory) |
160 | } |
161 | |
162 | fn reregister( |
163 | &mut self, |
164 | poll: &mut calloop::Poll, |
165 | token_factory: &mut calloop::TokenFactory, |
166 | ) -> calloop::Result<()> { |
167 | self.file.reregister(poll, token_factory) |
168 | } |
169 | |
170 | fn unregister(&mut self, poll: &mut calloop::Poll) -> calloop::Result<()> { |
171 | self.file.unregister(poll) |
172 | } |
173 | } |
174 | |