veridian_kernel/services/shell/state.rs
1//! Global shell state management.
2//!
3//! Manages the singleton Shell instance using OnceLock for safe
4//! initialization across all architectures (x86_64, AArch64, RISC-V).
5
6use super::Shell;
7
8/// Global shell instance using OnceLock for safe initialization.
9static SHELL: crate::sync::once_lock::OnceLock<Shell> = crate::sync::once_lock::OnceLock::new();
10
11/// Initialize the shell.
12///
13/// Creates the global Shell singleton. Subsequent calls are no-ops with a
14/// warning printed to the console.
15pub fn init() {
16 #[allow(unused_imports)]
17 use crate::println;
18
19 match SHELL.set(Shell::new()) {
20 Ok(()) => {
21 #[cfg(target_arch = "aarch64")]
22 {
23 crate::arch::aarch64::direct_uart::direct_print_str(
24 "[SHELL] Shell module loaded\n",
25 );
26 }
27 #[cfg(not(target_arch = "aarch64"))]
28 println!("[SHELL] Shell module loaded");
29 }
30 Err(_) => {
31 println!("[SHELL] WARNING: Already initialized! Skipping re-initialization.");
32 }
33 }
34}
35
36/// Get the global shell.
37///
38/// # Panics
39///
40/// Panics if the shell has not been initialized via [`init`].
41/// Prefer [`try_get_shell`] in contexts where a panic is unacceptable.
42pub fn get_shell() -> &'static Shell {
43 SHELL.get().expect("Shell not initialized")
44}
45
46/// Try to get the global shell (non-panicking).
47///
48/// Returns `None` if the shell has not been initialized via [`init`].
49pub fn try_get_shell() -> Option<&'static Shell> {
50 SHELL.get()
51}
52
53/// Run shell as a process.
54///
55/// This function never returns.
56pub fn run_shell() -> ! {
57 let shell = get_shell();
58 shell.run()
59}