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 let dispatcher = unsafe {
92 fdf::DispatcherRef::from_raw(ptr::NonNull::new(dispatcher).expect("null dispatcher"))
93 };
94 struct HandleInfo {
95 handle: zx::NullableHandle,
96 id: fuchsia_runtime::HandleInfo,
97 }
98 let handle_infos = handle.iter().zip(handle_info.iter()).filter_map(|(handle, info)| {
99 Some(HandleInfo {
100 id: fuchsia_runtime::HandleInfo::try_from(info.clone()).ok()?,
101 handle: unsafe { zx::NullableHandle::from_raw(*handle) },
103 })
104 });
105
106 let mut incoming = vec![];
107 let mut outgoing_dir = None;
108 let mut lifecycle = None;
109 let mut config = None;
110 for handle_info in handle_infos {
111 let HandleInfo { id, handle } = handle_info;
112 match id.handle_type() {
113 fuchsia_runtime::HandleType::FileDescriptor => {
114 }
116 fuchsia_runtime::HandleType::NamespaceDirectory => {
117 let arg = id.arg() as usize;
118 if arg >= names.len() {
119 continue;
120 }
121 let Ok(path) = unsafe { ffi::CStr::from_ptr(names[arg]) }.to_str() else {
124 continue;
125 };
126 let Ok(path) = cm_types::NamespacePath::new(path) else {
127 continue;
128 };
129 let directory = fidl::Channel::from(handle);
130 incoming.push(cm_types::NamespaceEntry { path, directory: directory.into() });
131 }
132 fuchsia_runtime::HandleType::DirectoryRequest => {
133 let directory = fidl::Channel::from(handle);
134 outgoing_dir = Some(directory.into());
135 }
136 fuchsia_runtime::HandleType::Lifecycle => {
137 let ch = fidl::Channel::from(handle);
138 lifecycle = Some(ServerEnd::<LifecycleMarker>::from(ch));
139 }
140 fuchsia_runtime::HandleType::ComponentConfigVmo => {
141 let vmo = zx::Vmo::from(handle);
142 config = Some(vmo);
143 }
144 _ => {}
145 }
146 }
147
148 let lifecycle = lifecycle.expect("libfuchsia: expected lifecycle handle missing");
149 DsoAsyncArgs { incoming, outgoing_dir, dispatcher, lifecycle, config }
150}
151
152#[doc(hidden)]
154pub fn dso_fini() {
155 }
160
161#[doc(hidden)]
162pub fn adapt_to_pass_arguments<A, R>(f: impl FnOnce(A) -> R, args: A) -> impl FnOnce() -> R {
163 move || f(args)
164}