Skip to main content

hermit/syscalls/interfaces/
mod.rs

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