1use 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)]
10pub 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")]
18impl 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"))]
25impl 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")]
32impl 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")]
45impl 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"))]
58impl 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"))]
65impl From<OwnedFd> for ReadPipe {
66 fn from(owned: OwnedFd) -> Self {
67 ReadPipe { file: owned.into() }
68 }
69}
70
71#[cfg(feature = "calloop")]
72impl 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")]
79impl AsFd for ReadPipe {
80 fn as_fd(&self) -> BorrowedFd<'_> {
81 self.file.get_ref().as_fd()
82 }
83}
84
85#[cfg(not(feature = "calloop"))]
86impl AsRawFd for ReadPipe {
87 fn as_raw_fd(&self) -> RawFd {
88 self.file.as_raw_fd()
89 }
90}
91#[cfg(not(feature = "calloop"))]
92
93impl AsFd for ReadPipe {
94 fn as_fd(&self) -> BorrowedFd<'_> {
95 self.file.as_fd()
96 }
97}
98
99#[cfg(feature = "calloop")]
100impl IntoRawFd for ReadPipe {
101 fn into_raw_fd(self) -> RawFd {
102 self.file.unwrap().as_raw_fd()
103 }
104}
105
106#[cfg(feature = "calloop")]
107impl 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"))]
114impl IntoRawFd for ReadPipe {
115 fn into_raw_fd(self) -> RawFd {
116 self.file.into_raw_fd()
117 }
118}
119
120#[cfg(not(feature = "calloop"))]
121impl From<ReadPipe> for OwnedFd {
122 fn from(read_pipe: ReadPipe) -> Self {
123 read_pipe.file.into()
124 }
125}
126
127#[cfg(feature = "calloop")]
128impl 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