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 NonNull<u8>) -> i32,
69) -> ! {
70 sysapi_init(args, env, *task_abi_structures);
71
72 fn c_main_args(args: RawSliceMut<NonNullSlice<u8>>) -> (i32, *const NonNull<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() * 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 NonNull<u8>, args.len())
84 };
85
86 for (i, arg) in argv_slice.iter().enumerate() {
87 c_argv_slice[i] = arg.as_non_null();
88 }
89
90 (args.len() as i32, c_argv_slice.as_ptr())
91 }
92
93 let (argc, argv) = c_main_args(args);
94 let result = main(argc, argv);
95 syscalls::exit(result as usize)
96}