Skip to main content

starnix_core/vfs/pseudo/
vec_directory.rs

1// Copyright 2022 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::task::CurrentTask;
6use crate::vfs::{
7    DirectoryEntryType, DirentSink, FileObject, FileOps, FsString, emit_dotdot,
8    fileops_impl_directory, fileops_impl_noop_sync, fileops_impl_unbounded_seek,
9};
10use starnix_uapi::errors::Errno;
11use starnix_uapi::ino_t;
12
13/// A directory entry used for [`VecDirectory`].
14#[derive(Debug, PartialEq, Eq, Clone, PartialOrd, Ord)]
15pub struct VecDirectoryEntry {
16    /// The type of the directory entry (directory, regular, socket, etc).
17    pub entry_type: DirectoryEntryType,
18
19    /// The name of the directory entry.
20    pub name: FsString,
21
22    /// Optional inode associated with the entry. If `None`, the entry will be auto-assigned one.
23    pub inode: Option<ino_t>,
24}
25
26/// A FileOps that iterates over a vector of [`VecDirectoryEntry`].
27pub struct VecDirectory(Vec<VecDirectoryEntry>);
28
29impl VecDirectory {
30    pub fn new_file(entries: Vec<VecDirectoryEntry>) -> Box<dyn FileOps> {
31        Box::new(Self(entries))
32    }
33}
34
35impl FileOps for VecDirectory {
36    fileops_impl_directory!();
37    fileops_impl_noop_sync!();
38    fileops_impl_unbounded_seek!();
39
40    fn readdir(
41        &self,
42        file: &FileObject,
43        _current_task: &CurrentTask,
44        sink: &mut dyn DirentSink,
45    ) -> Result<(), Errno> {
46        emit_dotdot(file, sink)?;
47
48        // Skip through the entries until the current offset is reached.
49        // Subtract 2 from the offset to account for `.` and `..`.
50        for entry in self.0.iter().skip(sink.offset() as usize - 2) {
51            // Assign an inode if one wasn't set.
52            let inode = entry.inode.unwrap_or_else(|| file.fs.allocate_ino());
53            sink.add(inode, sink.offset() + 1, entry.entry_type, entry.name.as_ref())?;
54        }
55        Ok(())
56    }
57}