Macro offset_ptr

Source
macro_rules! offset_ptr {
    ($entry_ptr:expr, d_reclen) => { ... };
    ($entry_ptr:expr, d_namlen) => { ... };
    ($entry_ptr:expr, d_ino) => { ... };
    ($entry_ptr:expr, $field:ident) => { ... };
}
Expand description

A helper macro to safely access dirent(64 on linux)’s fields of a libc::dirent/libc::dirent64 aka ‘dirent-type’ struct by offset.

§Safety

  • The caller must ensure that the pointer is valid and points to a ‘dirent-type’ struct.
  • The field name must be a valid field of the ‘dirent-type’ struct.

§Field Aliases

  • On BSD systems (FreeBSD, OpenBSD, NetBSD, DragonFly), d_ino is aliased to d_fileno Example: offset_ptr!(entry_ptr, d_ino) -> aliases to d_fileno and returns the VALUE of an inode(u64) (internal consistency, be glad it works!)
  • On Linux, d_reclen is used to access the record length directly, this is a special case, since it is not aligned like the others. Example: offset_ptr!(entry_ptr, d_reclen) -> returns the record length as usize (internal consistency, be glad it works!)
  • On MacOS/BSD, d_namlen is used to access the name length directly, this is a special case, since it is not aligned similarly to d_reclen. the other fields are accessed normally, as raw pointers to the field /// # Usage
let entry_ptr: *const libc::dirent = ...; // Assume this is a valid pointer to a dirent struct
let d_name_ptr:*const _ = offset_ptr!(entry_ptr, d_name);
let d_reclen:usize = offset_ptr!(entry_ptr, d_reclen);

let d_namlen:usize = offset_ptr!(entry_ptr, d_namlen); // This is a special case for BSD and MacOS, where d_namlen is available
let d_ino_ptr :u64= offset_ptr!(entry_ptr, d_ino); // This