1use core::ptr::NonNull;
3
4use crate::{
5 alloc::GLOBAL_SYSTEM_ALLOCATOR,
6 syscalls::{self},
7};
8use safa_abi::raw::{processes::AbiStructures, NonNullSlice, RawSliceMut};
9
10use super::{
11 args::{RawArgs, RAW_ARGS},
12 env::RAW_ENV,
13 stdio::init_meta,
14};
15
16fn init_args(args: RawSliceMut<NonNullSlice<u8>>) {
19 unsafe {
20 let slice = args
21 .into_slice_mut()
22 .map(|inner| RawArgs::new(NonNull::new_unchecked(inner as *mut _)));
23 RAW_ARGS.init(slice)
24 }
25}
26
27fn init_env(env: RawSliceMut<NonNullSlice<u8>>) {
28 unsafe {
29 let slice = env
30 .into_slice_mut()
31 .map(|inner| RawArgs::new(NonNull::new_unchecked(inner as *mut _)));
32 RAW_ENV.init(slice)
33 }
34}
35
36#[cfg_attr(
41 not(any(feature = "std", feature = "rustc-dep-of-std")),
42 unsafe(no_mangle)
43)]
44#[inline(always)]
45pub extern "C" fn sysapi_init(
46 args: RawSliceMut<NonNullSlice<u8>>,
47 env: RawSliceMut<NonNullSlice<u8>>,
48 task_abi_structures: AbiStructures,
49) {
50 init_args(args);
51 init_env(env);
52 init_meta(task_abi_structures);
53}
54
55#[cfg_attr(
61 not(any(feature = "std", feature = "rustc-dep-of-std")),
62 unsafe(no_mangle)
63)]
64pub unsafe extern "C" fn _c_api_init(
65 args: RawSliceMut<NonNullSlice<u8>>,
66 env: RawSliceMut<NonNullSlice<u8>>,
67 task_abi_structures: *const AbiStructures,
68 main: extern "C" fn(argc: i32, argv: *const *const u8) -> i32,
69) -> ! {
70 sysapi_init(args, env, *task_abi_structures);
71
72 fn c_main_args(args: RawSliceMut<NonNullSlice<u8>>) -> (i32, *const *const u8) {
74 let argv_slice = unsafe { args.into_slice_mut().unwrap_or_default() };
75 if argv_slice.is_empty() {
76 return (0, core::ptr::null());
77 }
78
79 let bytes = (args.len() + 1) * size_of::<usize>();
80
81 let c_argv_bytes = GLOBAL_SYSTEM_ALLOCATOR.allocate(bytes).unwrap();
82 let c_argv_slice = unsafe {
83 core::slice::from_raw_parts_mut(c_argv_bytes.as_ptr() as *mut *const u8, args.len() + 1)
84 };
85
86 for (i, arg) in argv_slice.iter().enumerate() {
87 c_argv_slice[i] = arg.as_ptr();
88 }
89
90 c_argv_slice[args.len()] = core::ptr::null();
91
92 (args.len() as i32, c_argv_slice.as_ptr())
93 }
94
95 let (argc, argv) = c_main_args(args);
96 let result = main(argc, argv);
97 syscalls::process::exit(result as usize)
98}