1use fdf::AutoReleaseDispatcher;
6pub use fuchsia_dso_macro::main;
7
8use fidl::endpoints::ServerEnd;
9use fidl_fuchsia_process_lifecycle::LifecycleMarker;
10
11#[doc(hidden)]
13pub fn dso_init(
14 _handle_count: u32,
15 _handle: *mut ::zx::sys::zx_handle_t,
16 _handle_info: *mut u32,
17 _name_count: u32,
18 _names: *mut *const ::std::ffi::c_char,
19 _argc: ::std::ffi::c_int,
20 _argv: *mut *const ::std::ffi::c_char,
21 _envp: *mut *const ::std::ffi::c_char,
22) {
23 }
30
31#[derive(Debug)]
33pub struct DsoAsyncArgs {
34 pub incoming: Vec<cm_types::NamespaceEntry>,
36 pub outgoing_dir: Option<fidl::endpoints::ServerEnd<::fidl_fuchsia_io::DirectoryMarker>>,
38 pub dispatcher: AutoReleaseDispatcher,
40 pub lifecycle: ServerEnd<LifecycleMarker>,
43 pub config: Option<zx::Vmo>,
45}
46
47#[doc(hidden)]
54pub struct DsoStartAsyncPayload {
55 pub handle_count: u32,
56 pub handle: *mut ::zx::sys::zx_handle_t,
57 pub handle_info: *mut u32,
58 pub name_count: u32,
59 pub names: *mut *const ::std::ffi::c_char,
60 pub argc: ::std::ffi::c_int,
61 pub argv: *mut *const ::std::ffi::c_char,
62 pub envp: *mut *const ::std::ffi::c_char,
63 pub dispatcher: *mut ::std::ffi::c_void,
64}
65
66unsafe impl Send for DsoStartAsyncPayload {}
67
68#[doc(hidden)]
70pub fn dso_init_async(payload: DsoStartAsyncPayload) -> DsoAsyncArgs {
71 use std::{ffi, ptr, slice};
72 let DsoStartAsyncPayload {
73 handle_count,
74 handle,
75 handle_info,
76 name_count,
77 names,
78 argc: _, argv: _, envp: _, dispatcher,
82 } = payload;
83
84 let handle = unsafe { slice::from_raw_parts(handle, handle_count as usize) };
86 let handle_info = unsafe { slice::from_raw_parts(handle_info, handle_count as usize) };
88 let names = unsafe { slice::from_raw_parts(names, name_count as usize) };
90 let dispatcher = dispatcher as *mut fdf_sys::fdf_dispatcher_t;
91 assert_eq!(
96 unsafe { fdf_sys::fdf_testing_set_default_dispatcher(dispatcher) },
97 zx::sys::ZX_OK,
98 "fdf_testing_set_default_dispatcher"
99 );
100 let dispatcher = unsafe {
102 fdf::AutoReleaseDispatcher::from_raw(
103 ptr::NonNull::new(dispatcher).expect("null dispatcher"),
104 )
105 };
106 struct HandleInfo {
107 handle: zx::NullableHandle,
108 id: fuchsia_runtime::HandleInfo,
109 }
110 let handle_infos = handle.iter().zip(handle_info.iter()).filter_map(|(handle, info)| {
111 Some(HandleInfo {
112 id: fuchsia_runtime::HandleInfo::try_from(info.clone()).ok()?,
113 handle: unsafe { zx::NullableHandle::from_raw(*handle) },
115 })
116 });
117
118 let mut incoming = vec![];
119 let mut outgoing_dir = None;
120 let mut lifecycle = None;
121 let mut config = None;
122 for handle_info in handle_infos {
123 let HandleInfo { id, handle } = handle_info;
124 match id.handle_type() {
125 fuchsia_runtime::HandleType::FileDescriptor => {
126 }
128 fuchsia_runtime::HandleType::NamespaceDirectory => {
129 let arg = id.arg() as usize;
130 if arg >= names.len() {
131 continue;
132 }
133 let Ok(path) = unsafe { ffi::CStr::from_ptr(names[arg]) }.to_str() else {
136 continue;
137 };
138 let Ok(path) = cm_types::NamespacePath::new(path) else {
139 continue;
140 };
141 let directory = fidl::Channel::from(handle);
142 incoming.push(cm_types::NamespaceEntry { path, directory: directory.into() });
143 }
144 fuchsia_runtime::HandleType::DirectoryRequest => {
145 let directory = fidl::Channel::from(handle);
146 outgoing_dir = Some(directory.into());
147 }
148 fuchsia_runtime::HandleType::Lifecycle => {
149 let ch = fidl::Channel::from(handle);
150 lifecycle = Some(ServerEnd::<LifecycleMarker>::from(ch));
151 }
152 fuchsia_runtime::HandleType::ComponentConfigVmo => {
153 let vmo = zx::Vmo::from(handle);
154 config = Some(vmo);
155 }
156 _ => {}
157 }
158 }
159
160 let lifecycle = lifecycle.expect("libfuchsia: expected lifecycle handle missing");
161 DsoAsyncArgs { incoming, outgoing_dir, dispatcher, lifecycle, config }
162}
163
164#[doc(hidden)]
166pub fn dso_fini() {
167 }
172
173#[doc(hidden)]
174pub fn adapt_to_pass_arguments<A, R>(f: impl FnOnce(A) -> R, args: A) -> impl FnOnce() -> R {
175 move || f(args)
176}