1#![doc(
36 html_logo_url = "https://aya-rs.dev/assets/images/crabby.svg",
37 html_favicon_url = "https://aya-rs.dev/assets/images/crabby.svg"
38)]
39#![cfg_attr(docsrs, feature(doc_cfg))]
40#![deny(missing_docs)]
41#![cfg_attr(
42 all(test, not(feature = "test-helpers")),
43 expect(unused_crate_dependencies, reason = "used in doctests")
44)]
45
46mod bpf;
47pub mod maps;
48pub mod pin;
49pub mod programs;
50pub mod sys;
51#[cfg(feature = "test-helpers")]
52pub mod test_helpers;
53pub mod util;
54
55use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, OwnedFd, RawFd};
56
57pub use aya_obj::btf::{Btf, BtfError};
58pub use bpf::*;
59pub use object::Endianness;
60pub use programs::{
61 RawTracePointRunOptions, RawTracePointTestRunResult, TestRun, TestRunAttrs, TestRunOptions,
62 TestRunResult,
63};
64#[doc(hidden)]
65pub use sys::netlink_set_link_up;
66
67#[derive(Debug)]
70struct MockableFd {
71 #[cfg(not(test))]
72 fd: OwnedFd,
73 #[cfg(test)]
74 fd: Option<OwnedFd>,
75}
76
77impl MockableFd {
78 #[cfg(test)]
79 const fn mock_signed_fd() -> i32 {
80 1337
81 }
82
83 #[cfg(test)]
84 const fn mock_unsigned_fd() -> u32 {
85 1337
86 }
87
88 #[cfg(not(test))]
89 const fn from_fd(fd: OwnedFd) -> Self {
90 Self { fd }
91 }
92
93 #[cfg(test)]
94 const fn from_fd(fd: OwnedFd) -> Self {
95 let fd = Some(fd);
96 Self { fd }
97 }
98
99 #[cfg(not(test))]
100 const fn inner(&self) -> &OwnedFd {
101 let Self { fd } = self;
102 fd
103 }
104
105 #[cfg(test)]
106 const fn inner(&self) -> &OwnedFd {
107 let Self { fd } = self;
108 fd.as_ref().unwrap()
109 }
110
111 #[cfg(not(test))]
112 fn into_inner(self) -> OwnedFd {
113 self.fd
114 }
115
116 #[cfg(test)]
117 fn into_inner(mut self) -> OwnedFd {
118 self.fd.take().unwrap()
119 }
120
121 fn try_clone(&self) -> std::io::Result<Self> {
122 let fd = self.inner();
123 let fd = fd.try_clone()?;
124 Ok(Self::from_fd(fd))
125 }
126}
127
128impl<T> From<T> for MockableFd
129where
130 OwnedFd: From<T>,
131{
132 fn from(value: T) -> Self {
133 let fd = OwnedFd::from(value);
134 Self::from_fd(fd)
135 }
136}
137
138impl AsFd for MockableFd {
139 fn as_fd(&self) -> BorrowedFd<'_> {
140 self.inner().as_fd()
141 }
142}
143
144impl AsRawFd for MockableFd {
145 fn as_raw_fd(&self) -> RawFd {
146 self.inner().as_raw_fd()
147 }
148}
149
150impl FromRawFd for MockableFd {
151 unsafe fn from_raw_fd(fd: RawFd) -> Self {
152 let fd = unsafe { OwnedFd::from_raw_fd(fd) };
153 Self::from_fd(fd)
154 }
155}
156
157#[cfg(test)]
158impl Drop for MockableFd {
159 fn drop(&mut self) {
160 use std::os::fd::{AsRawFd as _, IntoRawFd as _};
161
162 let Self { fd } = self;
163 let fd = fd.take().unwrap();
164 if fd.as_raw_fd() < Self::mock_signed_fd() {
165 drop(fd)
166 } else {
167 let _raw_fd = fd.into_raw_fd();
168 }
169 }
170}