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