vfs/lib.rs
1// Copyright 2019 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
5//! A library to create "pseudo" file systems. These file systems are backed by in process
6//! callbacks. Examples are: component configuration, debug information or statistics.
7
8#![recursion_limit = "1024"]
9
10pub mod test_utils;
11
12#[macro_use]
13pub mod common;
14
15pub mod execution_scope;
16pub use ::name;
17pub mod path;
18
19pub mod directory;
20pub mod file;
21pub mod node;
22pub mod object_request;
23mod protocols;
24pub mod remote;
25mod request_handler;
26pub mod service;
27pub mod symlink;
28pub mod temp_clone;
29pub mod token_registry;
30pub mod tree_builder;
31
32// --- pseudo_directory ---
33
34// pseudo_directory! uses helper functions that live in this module. It needs to be accessible
35// from the outside of this crate.
36#[doc(hidden)]
37pub mod pseudo_directory;
38
39/// Builds a pseudo directory using a simple DSL, potentially containing files and nested pseudo
40/// directories.
41///
42/// A directory is described using a sequence of rules of the following form:
43///
44/// <name> `=>` <something that implements DirectoryEntry>
45///
46/// separated by commas, with an optional trailing comma.
47///
48/// It generates a nested pseudo directory, using [`directory::immutable::Simple::new()`] then
49/// adding all the specified entries in it, by calling
50/// [`crate::directory::helper::DirectlyMutable::add_entry`].
51///
52/// Note: Names specified as literals (both `str` and `[u8]`) are compared during compilation time,
53/// so you should get a nice error message, if you specify the same entry name twice. As entry
54/// names can be specified as expressions, you can easily work around this check - you will still
55/// get an error, but it would be a `panic!` in this case. In any case the error message will
56/// contain details of the location of the generating macro and the duplicate entry name.
57///
58/// # Examples
59///
60/// This will construct a small tree of read-only files:
61/// ```
62/// let root = pseudo_directory! {
63/// "etc" => pseudo_directory! {
64/// "fstab" => read_only(b"/dev/fs /"),
65/// "passwd" => read_only(b"[redacted]"),
66/// "shells" => read_only(b"/bin/bash"),
67/// "ssh" => pseudo_directory! {
68/// "sshd_config" => read_only(b"# Empty"),
69/// },
70/// },
71/// "uname" => read_only(b"Fuchsia"),
72/// };
73/// ```
74pub use vfs_macros::pseudo_directory;
75
76pub use common::CreationMode;
77pub use object_request::{ObjectRequest, ObjectRequestRef, ToObjectRequest};
78pub use path::Path;
79pub use protocols::ProtocolsExt;
80
81// This allows the pseudo_directory! macro to use absolute paths within this crate to refer to the
82// helper functions. External crates that use pseudo_directory! will rely on the pseudo_directory
83// export above.
84#[cfg(test)]
85extern crate self as vfs;
86
87use directory::entry_container::Directory;
88use execution_scope::ExecutionScope;
89use fidl_fuchsia_io as fio;
90use std::sync::Arc;
91
92/// Helper function to serve a new connection to the directory at `path` under `root` with `flags`.
93/// Errors will be communicated via epitaph on the returned proxy. A new [`ExecutionScope`] will be
94/// created for the request.
95///
96/// To serve `root` itself, use [`crate::directory::serve`] or set `path` to [`Path::dot`].
97pub fn serve_directory<D: Directory + ?Sized>(
98 root: Arc<D>,
99 path: Path,
100 flags: fio::Flags,
101) -> fio::DirectoryProxy {
102 let (proxy, server) = fidl::endpoints::create_proxy::<fio::DirectoryMarker>();
103 let request = flags.to_object_request(server);
104 request.handle(|request| root.open3(ExecutionScope::new(), path, flags, request));
105 proxy
106}
107
108/// Helper function to serve a new connection to the file at `path` under `root` with `flags`.
109/// Errors will be communicated via epitaph on the returned proxy. A new [`ExecutionScope`] will be
110/// created for the request.
111///
112/// To serve an object that implements [`crate::file::File`], use [`crate::file::serve`].
113pub fn serve_file<D: Directory + ?Sized>(
114 root: Arc<D>,
115 path: Path,
116 flags: fio::Flags,
117) -> fio::FileProxy {
118 let (proxy, server) = fidl::endpoints::create_proxy::<fio::FileMarker>();
119 let request = flags.to_object_request(server);
120 request.handle(|request| root.open3(ExecutionScope::new(), path, flags, request));
121 proxy
122}