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