use super::{BUFSIZ, Buffer, FILE, constants}; use core::{cell::UnsafeCell, ptr}; use crate::{ fs::File, io::LineWriter, platform::types::*, sync::{Mutex, Once}, }; use alloc::{boxed::Box, vec::Vec}; // TODO: Change FILE to allow const fn initialization? pub struct GlobalFile(UnsafeCell); impl GlobalFile { fn new(file: c_int, flags: c_int) -> Self { let file = File::new(file); let writer = Box::new(LineWriter::new(unsafe { file.get_ref() })); GlobalFile(UnsafeCell::new(FILE { lock: Mutex::new(()), file, flags: constants::F_PERM | flags, read_buf: Buffer::Owned(vec![0; BUFSIZ as usize]), read_pos: 0, read_size: 0, unget: Vec::new(), writer, pid: None, orientation: 0, })) } pub fn get(&self) -> *mut FILE { self.0.get() } } // statics need to be Sync unsafe impl Sync for GlobalFile {} // TODO: Allow const fn initialization of FILE static DEFAULT_STDIN: Once = Once::new(); static DEFAULT_STDOUT: Once = Once::new(); static DEFAULT_STDERR: Once = Once::new(); pub fn default_stdin() -> &'static GlobalFile { DEFAULT_STDIN.call_once(|| GlobalFile::new(0, constants::F_NOWR)) } pub fn default_stdout() -> &'static GlobalFile { DEFAULT_STDOUT.call_once(|| GlobalFile::new(1, constants::F_NORD)) } pub fn default_stderr() -> &'static GlobalFile { DEFAULT_STDERR.call_once(|| GlobalFile::new(2, constants::F_NORD)) } #[unsafe(no_mangle)] pub static mut stdin: *mut FILE = ptr::null_mut(); #[unsafe(no_mangle)] pub static mut stdout: *mut FILE = ptr::null_mut(); #[unsafe(no_mangle)] pub static mut stderr: *mut FILE = ptr::null_mut();