driver_manager_utils/
pkg_utils.rs1use crate::errors::UtilsError;
6use fidl::endpoints::{ClientEnd, create_endpoints, create_proxy};
7use fidl_fuchsia_io as fio;
8
9pub async fn open_pkg_file(
10 pkg_dir: &fio::DirectoryProxy,
11 relative_binary_path: &str,
12) -> Result<zx::Vmo, UtilsError> {
13 let (file, server) = create_proxy::<fio::FileMarker>();
14 pkg_dir.open(
15 relative_binary_path,
16 fio::PERM_READABLE | fio::PERM_EXECUTABLE,
17 &fio::Options::default(),
18 server.into_channel(),
19 )?;
20
21 let vmo = file
22 .get_backing_memory(
23 fio::VmoFlags::READ | fio::VmoFlags::EXECUTE | fio::VmoFlags::PRIVATE_CLONE,
24 )
25 .await??;
26 Ok(vmo)
27}
28
29pub fn open_lib_dir(
30 pkg_dir: &fio::DirectoryProxy,
31) -> Result<ClientEnd<fio::DirectoryMarker>, UtilsError> {
32 let (lib_dir, server) = create_endpoints::<fio::DirectoryMarker>();
33 pkg_dir.open(
34 "lib",
35 fio::PERM_READABLE | fio::PERM_EXECUTABLE,
36 &fio::Options::default(),
37 server.into_channel(),
38 )?;
39 Ok(lib_dir)
40}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45 use fidl::endpoints::{ServerEnd, create_proxy_and_stream};
46 use futures::StreamExt;
47 use vfs::directory::entry_container::Directory;
48 use vfs::execution_scope::ExecutionScope;
49 use vfs::object_request::ToObjectRequest;
50 use vfs::pseudo_directory;
51
52 #[fuchsia::test]
53 async fn test_open_pkg_file() {
54 let (pkg_client, mut pkg_stream) = create_proxy_and_stream::<fio::DirectoryMarker>();
55
56 fuchsia_async::Task::local(async move {
57 while let Some(Ok(request)) = pkg_stream.next().await {
58 if let fio::DirectoryRequest::Open { flags, path, object, .. } = request {
59 assert_eq!(path, "bin/driver");
60 assert!(flags.contains(fio::Flags::PERM_READ_BYTES | fio::Flags::PERM_EXECUTE));
61
62 let server_end = ServerEnd::<fio::FileMarker>::new(object);
63 let mut stream = server_end.into_stream();
64
65 while let Some(Ok(request)) = stream.next().await {
66 if let fio::FileRequest::GetBackingMemory { flags: _, responder } = request
67 {
68 let vmo = zx::Vmo::create(12).unwrap();
69 vmo.write(b"test_content", 0).unwrap();
70 responder.send(Ok(vmo)).unwrap();
71 }
72 }
73 }
74 }
75 })
76 .detach();
77
78 let vmo = open_pkg_file(&pkg_client, "bin/driver").await.expect("Failed to open pkg file");
79 let mut buffer = vec![0; 12];
80 vmo.read(&mut buffer, 0).expect("Failed to read vmo");
81 assert_eq!(&buffer, b"test_content");
82 }
83
84 #[fuchsia::test]
85 async fn test_open_lib_dir() {
86 let pkg_dir = pseudo_directory! {
87 "lib" => pseudo_directory! {},
88 };
89
90 let (pkg_client, pkg_server) = create_proxy::<fio::DirectoryMarker>();
91 let scope = ExecutionScope::new();
92 let flags = fio::PERM_READABLE | fio::PERM_EXECUTABLE;
93 let mut object_request = flags.to_object_request(pkg_server.into_channel());
94 pkg_dir
95 .open(scope, vfs::path::Path::dot(), flags, &mut object_request)
96 .expect("Failed to open");
97
98 let lib_dir = open_lib_dir(&pkg_client).expect("Failed to open lib dir");
99 let lib_proxy = lib_dir.into_proxy();
100
101 let _attributes = lib_proxy
103 .get_attributes(fio::NodeAttributesQuery::empty())
104 .await
105 .expect("FIDL error")
106 .map_err(zx::Status::from_raw)
107 .expect("Failed to get attributes");
108 }
109}