hermit/syscalls/interfaces/
mod.rs

1use alloc::boxed::Box;
2use alloc::vec::Vec;
3
4pub use self::generic::*;
5pub use self::uhyve::*;
6use crate::{arch, env};
7
8mod generic;
9pub(crate) mod uhyve;
10
11pub trait SyscallInterface: Send + Sync {
12	fn init(&self) {
13		// Interface-specific initialization steps.
14	}
15
16	fn get_application_parameters(&self) -> (i32, *const *const u8, *const *const u8) {
17		let mut argv = Vec::new();
18
19		let name = Box::leak(Box::new("bin\0")).as_ptr();
20		argv.push(name);
21
22		let args = env::args();
23		debug!("Setting argv as: {args:?}");
24		for arg in args {
25			let ptr = Box::leak(format!("{arg}\0").into_boxed_str()).as_ptr();
26			argv.push(ptr);
27		}
28
29		let mut envv = Vec::new();
30
31		let envs = env::vars();
32		debug!("Setting envv as: {envs:?}");
33		for (key, value) in envs {
34			let ptr = Box::leak(format!("{key}={value}\0").into_boxed_str()).as_ptr();
35			envv.push(ptr);
36		}
37		envv.push(core::ptr::null::<u8>());
38
39		let argc = argv.len() as i32;
40		let argv = argv.leak().as_ptr();
41		// do we have more than a end marker? If not, return as null pointer
42		let envv = if envv.len() == 1 {
43			core::ptr::null::<*const u8>()
44		} else {
45			envv.leak().as_ptr()
46		};
47
48		(argc, argv, envv)
49	}
50
51	fn shutdown(&self, error_code: i32) -> ! {
52		// This is a stable message used for detecting exit codes for different hypervisors.
53		panic_println!("exit status {error_code}");
54
55		arch::processor::shutdown(error_code)
56	}
57}