Skip to main content

relibc/header/stdio/
default.rs

1use super::{BUFSIZ, Buffer, FILE, constants};
2use core::{cell::UnsafeCell, ptr};
3
4use crate::{fs::File, header::pthread, io::LineWriter, platform::types::c_int, sync::Once};
5use alloc::{boxed::Box, vec::Vec};
6
7// TODO: Change FILE to allow const fn initialization?
8pub struct GlobalFile(UnsafeCell<FILE>);
9
10impl GlobalFile {
11    fn new(file: c_int, flags: c_int) -> Self {
12        let file = File::new(file);
13        let writer = Box::new(LineWriter::new(unsafe { file.get_ref() }));
14        let mutex_attr = pthread::RlctMutexAttr {
15            ty: pthread::PTHREAD_MUTEX_RECURSIVE,
16            ..Default::default()
17        };
18        GlobalFile(UnsafeCell::new(FILE {
19            lock: pthread::RlctMutex::new(&mutex_attr).unwrap(),
20
21            file,
22            flags: constants::F_PERM | flags,
23            read_buf: Buffer::Owned(vec![0; BUFSIZ as usize]),
24            read_pos: 0,
25            read_size: 0,
26            unget: Vec::new(),
27            writer,
28
29            pid: None,
30
31            orientation: 0,
32        }))
33    }
34    pub fn get(&self) -> *mut FILE {
35        self.0.get()
36    }
37}
38// statics need to be Sync
39unsafe impl Sync for GlobalFile {}
40
41// TODO: Allow const fn initialization of FILE
42static DEFAULT_STDIN: Once<GlobalFile> = Once::new();
43static DEFAULT_STDOUT: Once<GlobalFile> = Once::new();
44static DEFAULT_STDERR: Once<GlobalFile> = Once::new();
45
46pub fn default_stdin() -> &'static GlobalFile {
47    DEFAULT_STDIN.call_once(|| GlobalFile::new(0, constants::F_NOWR))
48}
49pub fn default_stdout() -> &'static GlobalFile {
50    DEFAULT_STDOUT.call_once(|| GlobalFile::new(1, constants::F_NORD))
51}
52pub fn default_stderr() -> &'static GlobalFile {
53    DEFAULT_STDERR.call_once(|| GlobalFile::new(2, constants::F_NORD))
54}
55
56#[unsafe(no_mangle)]
57pub static mut stdin: *mut FILE = ptr::null_mut();
58#[unsafe(no_mangle)]
59pub static mut stdout: *mut FILE = ptr::null_mut();
60#[unsafe(no_mangle)]
61pub static mut stderr: *mut FILE = ptr::null_mut();