1#![allow(non_camel_case_types)]
24#![cfg(unix)]
25
26use measure_null_str::{MeasuredNullTermStr, NullTermStr};
31
32
33pub trait HasInode {
34 fn ino(&self) -> libc::ino_t;
35}
36pub trait HasEagerType {
37 fn eager_file_type(&self) -> libc::c_uchar;
38}
39pub trait HasNoEagerType {}
40pub trait HasNameLen {
41 fn name_len(&self) -> usize;
42}
43pub trait MeasureNameLen {
44 fn measure_name_len<'s>(&self, s: NullTermStr<'s>) -> &'s MeasuredNullTermStr { s.measure() }
45}
46impl<M> MeasureNameLen for M
47where M: HasNameLen
48{
49 fn measure_name_len<'s>(&self, s: NullTermStr<'s>) -> &'s MeasuredNullTermStr {
50 let n = self.name_len();
51 unsafe { MeasuredNullTermStr::given_measurement(s, n) }
52 }
53}
54
55macro_rules! rename_imports {
56 (use64) => {
57 pub use libc::{dirent64, fstatat64, ino64_t, openat64, readdir64, stat64};
58 };
59 (rename64) => {
60 pub use libc::{
61 dirent as dirent64, fstatat as fstatat64, ino_t as ino64_t, openat as openat64,
62 readdir as readdir64, stat as stat64,
63 };
64 };
65}
66macro_rules! generate_dirent {
67 () => {
68 #[derive(Copy, Clone, Debug)]
69 pub struct dirent64_min {}
70 impl dirent64_min {
71 pub unsafe const fn new(_entry_ptr: *const dirent64) -> Self { Self {} }
72 }
73 };
74 (d_ino) => {
75 #[derive(Copy, Clone, Debug)]
76 pub struct dirent64_min {
77 pub d_ino: libc::ino64_t,
78 }
79 impl dirent64_min {
80 pub unsafe fn new(entry_ptr: *const dirent64) -> Self {
81 unsafe {
82 Self {
83 d_ino: (*entry_ptr).ino(),
87 }
88 }
89 }
90 }
91 impl HasInode for dirent64_min {
92 fn ino(&self) -> libc::ino64_t { self.d_ino }
93 }
94 };
95 (d_ino, d_type) => {
96 #[derive(Copy, Clone, Debug)]
97 pub struct dirent64_min {
98 pub d_ino: libc::ino64_t,
99 pub d_type: libc::c_uchar,
100 }
101 impl dirent64_min {
102 pub unsafe fn new(entry_ptr: *const dirent64) -> Self {
103 unsafe {
104 Self {
105 d_ino: (*entry_ptr).ino(),
106 d_type: (*entry_ptr).eager_file_type(),
107 }
108 }
109 }
110 }
111 impl HasInode for dirent64_min {
112 fn ino(&self) -> libc::ino64_t { self.d_ino }
113 }
114 impl HasEagerType for dirent64_min {
115 fn eager_file_type(&self) -> libc::c_uchar { self.d_type }
116 }
117 };
118 (d_ino, d_type, d_namlen) => {
119 #[derive(Copy, Clone, Debug)]
120 pub struct dirent64_min {
121 pub d_ino: libc::ino64_t,
122 pub d_type: libc::c_uchar,
123 pub d_namlen: libc::c_uchar,
124 }
125 impl dirent64_min {
126 pub unsafe fn new(entry_ptr: *const dirent64) -> Self {
127 unsafe {
128 Self {
129 d_ino: (*entry_ptr).ino(),
130 d_type: (*entry_ptr).eager_file_type(),
131 d_namlen: (*entry_ptr).name_len(),
132 }
133 }
134 }
135 }
136 impl HasInode for dirent64_min {
137 fn ino(&self) -> libc::ino64_t { self.d_ino }
138 }
139 impl HasEagerType for dirent64_min {
140 fn eager_file_type(&self) -> libc::c_uchar { self.d_type }
141 }
142 impl HasNameLen for dirent64_min {
143 fn name_len(&self) -> usize { self.d_namlen }
144 }
145 };
146 }
147macro_rules! generate_imports {
148 (no_r, $use64:tt) => {
149 generate_dirent!();
150 rename_imports!($use64);
151 };
152 (no_r,d_ino, $use64:tt) => {
153 generate_dirent!(d_ino);
154 rename_imports!($use64);
155 };
156 (no_r,d_ino,d_type, $use64:tt) => {
157 generate_dirent!(d_ino, d_type);
158 rename_imports!($use64);
159 };
160 (no_r,d_ino,d_type,d_namlen, $use64:tt) => {
161 generate_dirent!(d_ino, d_type, d_namlen);
162 rename_imports!($use64);
163 };
164}
165
166cfg_if::cfg_if! {
167 if #[cfg(target_os = "android")] {
168 generate_imports!(no_r, d_ino, d_type, rename64);
169 } else if #[cfg(target_os = "vita")] {
170 generate_imports!(no_r, rename64);
171 } else if #[cfg(any(
172 target_os = "solaris",
173 target_os = "illumos",
174 target_os = "aix",
175 target_os = "nto",
176 ))] {
177 generate_imports!(no_r, d_ino, rename64);
178 } else if #[cfg(any(target_os = "fuchsia", target_os = "redox"))] {
179 generate_imports!(no_r, d_ino, d_type, rename64);
180 } else if #[cfg(target_os = "hurd")] {
181 generate_imports!(no_r, d_ino, d_type, d_namlen, use64);
182 } else if #[cfg(target_os = "linux")] {
183 cfg_if::cfg_if! {
184 if #[cfg(target_env = "musl")] {
185 generate_imports!(no_r, d_ino, d_type, rename64);
186 } else {
187 generate_imports!(no_r, d_ino, d_type, use64);
188 }
189 }
190 } else if #[cfg(target_os = "l4re")] {
191 generate_imports!(no_r, d_ino, d_type, use64);
192 } else if #[cfg(target_os = "nuttx")] {
193 generate_imports!(no_r, rename64);
194 } else if #[cfg(any(target_os = "haiku", target_os = "vxworks"))] {
195 generate_imports!(no_r, d_ino, rename64);
196 } else if #[cfg(any(
197 target_os = "netbsd",
198 target_os = "openbsd",
199 target_os = "freebsd",
200 target_os = "dragonfly",
201 target_vendor = "apple",
202 ))] {
203 generate_imports!(no_r, d_ino, d_type, d_namlen, rename64);
204 } else {
205 generate_imports!(no_r, d_ino, d_type, rename64);
206 }
207}
208
209cfg_if::cfg_if! {
210 if #[cfg(any(
211 target_os = "freebsd",
212 target_os = "openbsd",
213 target_os = "netbsd",
214 target_os = "dragonfly"
215 ))] {
216 impl HasInode for dirent64 {
217 fn ino(&self) -> libc::ino64_t { self.d_fileno }
218 }
219 } else if #[cfg(any(target_os = "vita", target_os = "nuttx"))] {
220 } else {
221 impl HasInode for dirent64 {
222 fn ino(&self) -> libc::ino64_t { self.d_ino }
223 }
224 }
225}
226
227cfg_if::cfg_if! {
228 if #[cfg(any(
229 target_os = "solaris",
230 target_os = "illumos",
231 target_os = "haiku",
232 target_os = "vxworks",
233 target_os = "aix",
234 target_os = "nto",
235 target_os = "vita",
236 ))] {
237 impl HasNoEagerType for dirent64 {}
238 } else {
239 impl HasEagerType for dirent64 {
240 fn eager_file_type(&self) -> libc::c_uchar { self.d_type }
241 }
242 }
243}
244
245cfg_if::cfg_if! {
246 if #[cfg(any(
247 target_os = "hurd",
248 target_os = "netbsd",
249 target_os = "openbsd",
250 target_os = "freebsd",
251 target_os = "dragonfly",
252 target_vendor = "apple",
253 ))] {
254 impl HasNameLen for dirent64 {
255 fn name_len(&self) -> usize { self.d_namlen }
256 }
257 } else {
258 impl MeasureNameLen for dirent64 {}
259 impl MeasureNameLen for dirent64_min {}
260 }
261}