relibc/header/unistd/
path.rs1use core::slice::Split;
2
3use arrayvec::ArrayVec;
4
5use crate::{c_str::CStr, header::limits::PATH_MAX};
6
7pub struct PathSearchIter<'a> {
8 file_bytes: &'a [u8],
9 path_splits: Split<'a, u8, fn(&u8) -> bool>,
10}
11
12const PATH_SEPARATOR: u8 = b':';
13
14impl<'a> PathSearchIter<'a> {
15 pub fn new(file_bytes: &'a [u8], path_env: &'a CStr) -> Self {
18 Self {
19 file_bytes,
20 path_splits: path_env.to_bytes().split(|&b| b == PATH_SEPARATOR),
21 }
22 }
23}
24
25impl<'a> Iterator for PathSearchIter<'a> {
26 type Item = ArrayVec<u8, PATH_MAX>;
27
28 fn next(&mut self) -> Option<Self::Item> {
29 for path in &mut self.path_splits {
30 let len = path.len() + self.file_bytes.len() + 2;
31 if len > PATH_MAX {
32 continue;
33 }
34 let mut program: ArrayVec<u8, PATH_MAX> = ArrayVec::new();
35 program.try_extend_from_slice(path).unwrap();
36 program.push(b'/');
37 program.try_extend_from_slice(self.file_bytes).unwrap();
38 program.push(b'\0');
39 return Some(program);
40 }
41
42 None
43 }
44}