relibc/header/stdio/
default.rs1use 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
7pub 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}
38unsafe impl Sync for GlobalFile {}
40
41static 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();