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