#![allow(non_camel_case_types)]
#![cfg(unix)]
use measure_null_str::{MeasuredNullTermStr, NullTermStr};
pub trait HasInode {
fn ino(&self) -> libc::ino_t;
}
pub trait HasEagerType {
fn eager_file_type(&self) -> libc::c_uchar;
}
pub trait HasNoEagerType {}
pub trait HasNameLen {
fn name_len(&self) -> usize;
}
pub trait MeasureNameLen {
fn measure_name_len<'s>(&self, s: NullTermStr<'s>) -> &'s MeasuredNullTermStr { s.measure() }
}
impl<M> MeasureNameLen for M
where M: HasNameLen
{
fn measure_name_len<'s>(&self, s: NullTermStr<'s>) -> &'s MeasuredNullTermStr {
let n = self.name_len();
unsafe { MeasuredNullTermStr::given_measurement(s, n) }
}
}
macro_rules! rename_imports {
(use64) => {
pub use libc::{dirent64, fstatat64, ino64_t, openat64, readdir64, stat64};
};
(rename64) => {
pub use libc::{
dirent as dirent64, fstatat as fstatat64, ino_t as ino64_t, openat as openat64,
readdir as readdir64, stat as stat64,
};
};
}
macro_rules! generate_dirent {
() => {
#[derive(Copy, Clone, Debug)]
pub struct dirent64_min {}
impl dirent64_min {
pub unsafe const fn new(_entry_ptr: *const dirent64) -> Self { Self {} }
}
};
(d_ino) => {
#[derive(Copy, Clone, Debug)]
pub struct dirent64_min {
pub d_ino: libc::ino64_t,
}
impl dirent64_min {
pub unsafe fn new(entry_ptr: *const dirent64) -> Self {
unsafe {
Self {
d_ino: (*entry_ptr).ino(),
}
}
}
}
impl HasInode for dirent64_min {
fn ino(&self) -> libc::ino64_t { self.d_ino }
}
};
(d_ino, d_type) => {
#[derive(Copy, Clone, Debug)]
pub struct dirent64_min {
pub d_ino: libc::ino64_t,
pub d_type: libc::c_uchar,
}
impl dirent64_min {
pub unsafe fn new(entry_ptr: *const dirent64) -> Self {
unsafe {
Self {
d_ino: (*entry_ptr).ino(),
d_type: (*entry_ptr).eager_file_type(),
}
}
}
}
impl HasInode for dirent64_min {
fn ino(&self) -> libc::ino64_t { self.d_ino }
}
impl HasEagerType for dirent64_min {
fn eager_file_type(&self) -> libc::c_uchar { self.d_type }
}
};
(d_ino, d_type, d_namlen) => {
#[derive(Copy, Clone, Debug)]
pub struct dirent64_min {
pub d_ino: libc::ino64_t,
pub d_type: libc::c_uchar,
pub d_namlen: libc::c_uchar,
}
impl dirent64_min {
pub unsafe fn new(entry_ptr: *const dirent64) -> Self {
unsafe {
Self {
d_ino: (*entry_ptr).ino(),
d_type: (*entry_ptr).eager_file_type(),
d_namlen: (*entry_ptr).name_len(),
}
}
}
}
impl HasInode for dirent64_min {
fn ino(&self) -> libc::ino64_t { self.d_ino }
}
impl HasEagerType for dirent64_min {
fn eager_file_type(&self) -> libc::c_uchar { self.d_type }
}
impl HasNameLen for dirent64_min {
fn name_len(&self) -> usize { self.d_namlen }
}
};
}
macro_rules! generate_imports {
(no_r, $use64:tt) => {
generate_dirent!();
rename_imports!($use64);
};
(no_r,d_ino, $use64:tt) => {
generate_dirent!(d_ino);
rename_imports!($use64);
};
(no_r,d_ino,d_type, $use64:tt) => {
generate_dirent!(d_ino, d_type);
rename_imports!($use64);
};
(no_r,d_ino,d_type,d_namlen, $use64:tt) => {
generate_dirent!(d_ino, d_type, d_namlen);
rename_imports!($use64);
};
}
cfg_if::cfg_if! {
if #[cfg(target_os = "android")] {
generate_imports!(no_r, d_ino, d_type, rename64);
} else if #[cfg(target_os = "vita")] {
generate_imports!(no_r, rename64);
} else if #[cfg(any(
target_os = "solaris",
target_os = "illumos",
target_os = "aix",
target_os = "nto",
))] {
generate_imports!(no_r, d_ino, rename64);
} else if #[cfg(any(target_os = "fuchsia", target_os = "redox"))] {
generate_imports!(no_r, d_ino, d_type, rename64);
} else if #[cfg(target_os = "hurd")] {
generate_imports!(no_r, d_ino, d_type, d_namlen, use64);
} else if #[cfg(target_os = "linux")] {
cfg_if::cfg_if! {
if #[cfg(target_env = "musl")] {
generate_imports!(no_r, d_ino, d_type, rename64);
} else {
generate_imports!(no_r, d_ino, d_type, use64);
}
}
} else if #[cfg(target_os = "l4re")] {
generate_imports!(no_r, d_ino, d_type, use64);
} else if #[cfg(target_os = "nuttx")] {
generate_imports!(no_r, rename64);
} else if #[cfg(any(target_os = "haiku", target_os = "vxworks"))] {
generate_imports!(no_r, d_ino, rename64);
} else if #[cfg(any(
target_os = "netbsd",
target_os = "openbsd",
target_os = "freebsd",
target_os = "dragonfly",
target_vendor = "apple",
))] {
generate_imports!(no_r, d_ino, d_type, d_namlen, rename64);
} else {
generate_imports!(no_r, d_ino, d_type, rename64);
}
}
cfg_if::cfg_if! {
if #[cfg(any(
target_os = "freebsd",
target_os = "openbsd",
target_os = "netbsd",
target_os = "dragonfly"
))] {
impl HasInode for dirent64 {
fn ino(&self) -> libc::ino64_t { self.d_fileno }
}
} else if #[cfg(any(target_os = "vita", target_os = "nuttx"))] {
} else {
impl HasInode for dirent64 {
fn ino(&self) -> libc::ino64_t { self.d_ino }
}
}
}
cfg_if::cfg_if! {
if #[cfg(any(
target_os = "solaris",
target_os = "illumos",
target_os = "haiku",
target_os = "vxworks",
target_os = "aix",
target_os = "nto",
target_os = "vita",
))] {
impl HasNoEagerType for dirent64 {}
} else {
impl HasEagerType for dirent64 {
fn eager_file_type(&self) -> libc::c_uchar { self.d_type }
}
}
}
cfg_if::cfg_if! {
if #[cfg(any(
target_os = "hurd",
target_os = "netbsd",
target_os = "openbsd",
target_os = "freebsd",
target_os = "dragonfly",
target_vendor = "apple",
))] {
impl HasNameLen for dirent64 {
fn name_len(&self) -> usize { self.d_namlen }
}
} else {
impl MeasureNameLen for dirent64 {}
impl MeasureNameLen for dirent64_min {}
}
}