use crate::ffi::fs as raw;
use crate::ffi::types::*;
use crate::error::{OsError, Result};
use crate::fs::nul_path;
pub struct Dir(*mut c_void);
impl Dir {
pub fn open(path: &[u8]) -> Result<Self> {
let mut buf = [0u8; 4096];
let p = nul_path(path, &mut buf)?;
let d = unsafe { raw::opendir(p) };
if d.is_null() { Err(OsError::last()) } else { Ok(Self(d)) }
}
pub fn next(&mut self) -> Option<DirEntry> {
loop {
let ent = unsafe { raw::readdir(self.0) };
if ent.is_null() { return None; }
let e = unsafe { &*ent };
let name_len = e.d_namlen as usize;
let name_bytes = &e.d_name[..name_len];
if name_bytes == b"." || name_bytes == b".." { continue; }
let mut name = [0u8; 256];
let copy_len = name_len.min(255);
name[..copy_len].copy_from_slice(&e.d_name[..copy_len]);
return Some(DirEntry {
ino: e.d_ino,
file_type: e.d_type,
name,
name_len: copy_len,
});
}
}
}
impl Drop for Dir {
fn drop(&mut self) {
unsafe { raw::closedir(self.0); }
}
}
pub struct DirEntry {
pub ino: u64,
pub file_type: u8,
name: [u8; 256],
name_len: usize,
}
impl DirEntry {
#[inline]
pub fn name(&self) -> &[u8] { &self.name[..self.name_len] }
}