1use core::ptr::NonNull;
3
4use safa_abi::{
5 ffi::{slice::Slice, str::Str},
6 process::AbiStructures,
7};
8
9use crate::{
10 alloc::GLOBAL_SYSTEM_ALLOCATOR,
11 exported_func,
12 process::env::RawEnv,
13 syscalls::{self},
14};
15
16use super::{
17 args::{RawArgs, RAW_ARGS},
18 env::RAW_ENV,
19 stdio::init_meta,
20};
21
22fn init_args(args: Option<NonNull<[&'static str]>>) {
25 unsafe {
26 let raw = RawArgs::new(args);
27 RAW_ARGS.init(raw)
28 }
29}
30
31fn init_env(env: Option<NonNull<[&'static [u8]]>>) {
32 unsafe {
33 let raw = RawEnv::new(env);
34 RAW_ENV.init(raw)
35 }
36}
37
38exported_func! {
39 pub extern "C" fn sysapi_init(
44 args: Slice<Str>,
45 env: Slice<Slice<u8>>,
46 task_abi_structures: AbiStructures,
47 ) {
48 unsafe {
49 let args = args.try_into_str_slices_mut(|_| true).expect("invalid args passed to sysapi_init");
50 let args_ptr = NonNull::new_unchecked(args as *mut [&'static str]) ;
51
52 let env = env.try_into_slices_ptr_mut(|_| true).expect("invalid env passed to sysapi_init");
53 let env_ptr = NonNull::new_unchecked(env as *mut [&'static [u8]]) ;
54
55 init_args(Some(args_ptr));
56 init_env(Some(env_ptr));
57 init_meta(task_abi_structures);
58 }
59 }
60}
61
62#[cfg_attr(
68 not(any(feature = "std", feature = "rustc-dep-of-std")),
69 unsafe(no_mangle)
70)]
71pub unsafe extern "C" fn _c_api_init(
72 args: Slice<Str>,
73 env: Slice<Slice<u8>>,
74 task_abi_structures: *const AbiStructures,
75 main: extern "C" fn(argc: i32, argv: *const *const u8) -> i32,
76) -> ! {
77 sysapi_init(args, env, *task_abi_structures);
78
79 fn c_main_args(args: Slice<Str>) -> (i32, *const *const u8) {
81 let argv_slice = unsafe {
82 args.try_as_slice()
83 .expect("argv passed to _c_api_init are invalid")
84 };
85
86 if argv_slice.is_empty() {
87 return (0, core::ptr::null());
88 }
89
90 let bytes = (args.len() + 1) * size_of::<usize>();
91
92 let c_argv_bytes = GLOBAL_SYSTEM_ALLOCATOR.allocate(bytes).unwrap();
93 let c_argv_slice = unsafe {
94 core::slice::from_raw_parts_mut(c_argv_bytes.as_ptr() as *mut *const u8, args.len() + 1)
95 };
96
97 for (i, arg) in argv_slice.iter().enumerate() {
98 c_argv_slice[i] = arg.as_ptr();
99 }
100
101 c_argv_slice[args.len()] = core::ptr::null();
102
103 (args.len() as i32, c_argv_slice.as_ptr())
104 }
105
106 let (argc, argv) = c_main_args(args);
107 let result = main(argc, argv);
108 syscalls::process::exit(result as usize)
109}