blob: 6127cb490c88688cf0714a85019ae5693e7bc604 [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use {
fidl::endpoints::ServerEnd,
fidl_fuchsia_io as fio,
std::sync::Arc,
vfs::{
directory::entry::DirectoryEntry, directory::immutable::simple as pfs,
execution_scope::ExecutionScope, file::vmo::asynchronous::read_only_static,
path::Path as fvfsPath, tree_builder::TreeBuilder,
},
};
// Simple directory type which is used to implement `ComponentStartInfo.runtime_directory`.
pub type RuntimeDirectory = Arc<pfs::Simple>;
pub struct RuntimeDirBuilder {
args: Vec<String>,
job_id: Option<u64>,
process_id: Option<u64>,
process_start_time: Option<i64>,
process_start_time_utc_estimate: Option<String>,
server_end: ServerEnd<fio::NodeMarker>,
}
impl RuntimeDirBuilder {
pub fn new(server_end: ServerEnd<fio::DirectoryMarker>) -> Self {
// Transform the server end to speak Node protocol only
let server_end = ServerEnd::<fio::NodeMarker>::new(server_end.into_channel());
Self {
args: vec![],
job_id: None,
process_id: None,
process_start_time: None,
process_start_time_utc_estimate: None,
server_end,
}
}
pub fn args(mut self, args: Vec<String>) -> Self {
self.args = args;
self
}
pub fn job_id(mut self, job_id: u64) -> Self {
self.job_id = Some(job_id);
self
}
pub fn process_id(mut self, process_id: u64) -> Self {
self.process_id = Some(process_id);
self
}
pub fn process_start_time(mut self, process_start_time: i64) -> Self {
self.process_start_time = Some(process_start_time);
self
}
pub fn process_start_time_utc_estimate(
mut self,
process_start_time_utc_estimate: Option<String>,
) -> Self {
self.process_start_time_utc_estimate = process_start_time_utc_estimate;
self
}
pub fn serve(mut self) -> RuntimeDirectory {
// Create the runtime tree structure
//
// runtime
// |- args
// | |- 0
// | |- 1
// | \- ...
// \- elf
// |- job_id
// \- process_id
let mut runtime_tree_builder = TreeBuilder::empty_dir();
let mut count: u32 = 0;
for arg in self.args.drain(..) {
runtime_tree_builder
.add_entry(["args", &count.to_string()], read_only_static(arg))
.expect("Failed to add arg to runtime directory");
count += 1;
}
if let Some(job_id) = self.job_id {
runtime_tree_builder
.add_entry(["elf", "job_id"], read_only_static(job_id.to_string()))
.expect("Failed to add job_id to runtime/elf directory");
}
if let Some(process_id) = self.process_id {
runtime_tree_builder
.add_entry(["elf", "process_id"], read_only_static(process_id.to_string()))
.expect("Failed to add process_id to runtime/elf directory");
}
if let Some(process_start_time) = self.process_start_time {
runtime_tree_builder
.add_entry(
["elf", "process_start_time"],
read_only_static(process_start_time.to_string()),
)
.expect("Failed to add process_start_time to runtime/elf directory");
}
if let Some(process_start_time_utc_estimate) = self.process_start_time_utc_estimate {
runtime_tree_builder
.add_entry(
["elf", "process_start_time_utc_estimate"],
read_only_static(process_start_time_utc_estimate),
)
.expect("Failed to add process_start_time_utc_estimate to runtime/elf directory");
}
let runtime_directory = runtime_tree_builder.build();
// Serve the runtime directory
runtime_directory.clone().open(
ExecutionScope::new(),
fio::OPEN_RIGHT_READABLE | fio::OPEN_RIGHT_WRITABLE,
0,
fvfsPath::dot(),
self.server_end,
);
runtime_directory
}
}