1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
//! ort: Open Router CLI
//! https://github.com/grahamking/ort
//!
//! MIT License
//! Copyright (c) 2025 Graham King
//!
use core::ffi::CStr;
extern crate alloc;
use alloc::string::{String, ToString};
use crate::{ErrorKind, OrtResult, libc, ort_error};
/// Iterator over the regular files in this directory.
pub struct DirFiles {
dir: *mut libc::DIR,
}
impl DirFiles {
pub fn new(p: &CStr) -> OrtResult<Self> {
let dir: *mut libc::DIR = unsafe { libc::opendir(p.as_ptr()) };
if dir.is_null() {
return Err(ort_error(ErrorKind::DirOpenFailed, "opendir returned null"));
}
Ok(DirFiles { dir })
}
}
impl Iterator for DirFiles {
type Item = String;
fn next(&mut self) -> Option<Self::Item> {
unsafe {
loop {
let entry = libc::readdir(self.dir);
if entry.is_null() {
// This is how readdir tells us we hit the end
return None;
}
let name_ptr = (*entry).d_name.as_ptr();
if name_ptr.is_null() {
// File with no name??
continue;
}
let d_type = (*entry).d_type;
if d_type != libc::DT_REG {
// Not a regular file
// Technically readdir can return DT_UNKNOWN and we
// need to `stat` it. We're modern Linux only though.
continue;
}
let s = CStr::from_ptr(name_ptr).to_string_lossy().to_string();
return Some(s);
}
}
}
}
impl Drop for DirFiles {
fn drop(&mut self) {
unsafe { libc::closedir(self.dir) };
}
}