safa_api/process/
stdio.rs1use core::{cell::UnsafeCell, mem::MaybeUninit};
5
6use crate::{
7 exported_func,
8 syscalls::{self},
9};
10use safa_abi::{
11 ffi::option::COption,
12 process::{AbiStructures, ProcessStdio},
13};
14
15use crate::sync::cell::LazyCell;
16
17pub(super) struct StaticAbiStructures(UnsafeCell<MaybeUninit<AbiStructures>>);
18
19impl StaticAbiStructures {
20 pub unsafe fn init(&self, structures: AbiStructures) {
21 let ptr = self.0.get();
22 ptr.write(MaybeUninit::new(structures));
23 }
24
25 unsafe fn get(&'static self) -> &'static AbiStructures {
26 let ptr = self.0.get();
27 MaybeUninit::assume_init_ref(&*ptr)
28 }
29}
30
31unsafe impl Sync for StaticAbiStructures {}
32
33pub(super) static ABI_STRUCTURES: StaticAbiStructures =
34 StaticAbiStructures(UnsafeCell::new(MaybeUninit::zeroed()));
35
36static STDIO: LazyCell<ProcessStdio> = LazyCell::new(|| unsafe { ABI_STRUCTURES.get().stdio });
37static STDIN: LazyCell<usize> = LazyCell::new(|| {
38 let stdin: Option<usize> = STDIO.stdin.into();
39 if let Some(stdin) = stdin {
40 stdin
41 } else {
42 syscalls::fs::open_all("dev:/tty").expect("failed to fall back to `dev:/tty` for stdin")
43 }
44});
45
46static STDOUT: LazyCell<usize> = LazyCell::new(|| {
47 let stdout: Option<usize> = STDIO.stdout.into();
48 if let Some(stdout) = stdout {
49 stdout
50 } else {
51 syscalls::fs::open_all("dev:/tty").expect("failed to fall back to `dev:/tty` for stdout")
52 }
53});
54
55static STDERR: LazyCell<usize> = LazyCell::new(|| {
56 let stderr: Option<usize> = STDIO.stderr.into();
57 if let Some(stderr) = stderr {
58 stderr
59 } else {
60 syscalls::fs::open_all("dev:/tty").expect("failed to fall back to `dev:/tty` for stderr")
61 }
62});
63
64exported_func! {
65 pub extern "C" fn systry_get_stdout() -> COption<usize> {
67 STDIO.stdout.clone()
68 }
69}
70
71exported_func! {
72 pub extern "C" fn systry_get_stderr() -> COption<usize> {
74 STDIO.stderr.clone()
75 }
76}
77
78exported_func! {
79 pub extern "C" fn systry_get_stdin() -> COption<usize> {
81 STDIO.stdin.clone()
82 }
83}
84
85exported_func! {
86 pub extern "C" fn sysget_stdout() -> usize {
90 *STDOUT
91 }
92}
93
94exported_func! {
95 pub extern "C" fn sysget_stderr() -> usize {
99 *STDERR
100 }
101}
102
103exported_func! {
104 pub extern "C" fn sysget_stdin() -> usize {
108 *STDIN
109 }
110}
111
112pub fn init_meta(abi_structures: AbiStructures) {
113 unsafe { ABI_STRUCTURES.init(abi_structures) };
114}