diff --git a/include/bits/stdio.h b/include/bits/stdio.h index 16eb100bb47f46f9ddbab354ff7b689350df0c21..506ff549e369cfae666513b76698050a4966847d 100644 --- a/include/bits/stdio.h +++ b/include/bits/stdio.h @@ -2,6 +2,9 @@ #define _BITS_STDIO_H #define EOF (-1) +#define stdin __stdin() +#define stdout __stdout() +#define stderr __stderr() int fprintf(FILE * stream, const char * fmt, ...); int printf(const char * fmt, ...); diff --git a/src/locale/src/lib.rs b/src/locale/src/lib.rs index f71380b3533c2a3a388d891ed6cbb1a35ce0d842..34755f17208cf482c3f242f46864ca1f721284b8 100644 --- a/src/locale/src/lib.rs +++ b/src/locale/src/lib.rs @@ -9,6 +9,7 @@ use core::ptr; use platform::types::*; const EMPTY_PTR: *const c_char = "\0" as *const _ as *const c_char; +// Can't use &str because of the mutability static mut C_LOCALE: [c_char; 2] = [b'C' as c_char, 0]; #[repr(C)] @@ -64,7 +65,6 @@ pub extern "C" fn localeconv() -> *const lconv { #[no_mangle] pub unsafe extern "C" fn setlocale(_option: c_int, val: *const c_char) -> *mut c_char { if val.is_null() { - // Can't use string`` return C_LOCALE.as_mut_ptr() as *mut c_char; } // TODO actually implement diff --git a/src/stdio/src/default.rs b/src/stdio/src/default.rs index 840a6fa07ff1ef76d945ff7997403e6b153d1f40..25b5844719ec765fea972db7c62e146cc8d975ae 100644 --- a/src/stdio/src/default.rs +++ b/src/stdio/src/default.rs @@ -1,12 +1,25 @@ +use core::cell::UnsafeCell; use core::sync::atomic::AtomicBool; use core::ptr; use super::{constants, internal, BUFSIZ, FILE, UNGET}; +struct GlobalFile(UnsafeCell<FILE>); +impl GlobalFile { + const fn new(file: FILE) -> Self { + GlobalFile(UnsafeCell::new(file)) + } + fn get(&self) -> *mut FILE { + self.0.get() + } +} +// statics need to be Sync +unsafe impl Sync for GlobalFile {} + #[allow(non_upper_case_globals)] static mut default_stdin_buf: [u8; BUFSIZ as usize + UNGET] = [0; BUFSIZ as usize + UNGET]; #[allow(non_upper_case_globals)] -static mut default_stdin: FILE = FILE { +static mut default_stdin: GlobalFile = GlobalFile::new(FILE { flags: constants::F_PERM | constants::F_NOWR | constants::F_BADJ, rpos: ptr::null_mut(), rend: ptr::null_mut(), @@ -19,13 +32,13 @@ static mut default_stdin: FILE = FILE { buf_char: -1, unget: UNGET, lock: AtomicBool::new(false), -}; +}); #[allow(non_upper_case_globals)] static mut default_stdout_buf: [u8; BUFSIZ as usize] = [0; BUFSIZ as usize]; #[allow(non_upper_case_globals)] -static mut default_stdout: FILE = FILE { +static mut default_stdout: GlobalFile = GlobalFile::new(FILE { flags: constants::F_PERM | constants::F_NORD | constants::F_BADJ, rpos: ptr::null_mut(), rend: ptr::null_mut(), @@ -38,13 +51,13 @@ static mut default_stdout: FILE = FILE { buf_char: b'\n' as i8, unget: 0, lock: AtomicBool::new(false), -}; +}); #[allow(non_upper_case_globals)] static mut default_stderr_buf: [u8; BUFSIZ as usize] = [0; BUFSIZ as usize]; #[allow(non_upper_case_globals)] -static mut default_stderr: FILE = FILE { +static mut default_stderr: GlobalFile = GlobalFile::new(FILE { flags: constants::F_PERM | constants::F_NORD | constants::F_BADJ, rpos: ptr::null_mut(), rend: ptr::null_mut(), @@ -57,20 +70,19 @@ static mut default_stderr: FILE = FILE { buf_char: -1, unget: 0, lock: AtomicBool::new(false), -}; +}); -// Don't ask me how the casting below works, I have no idea -// " as *const FILE as *mut FILE" rust pls -// -// -- Tommoa -#[allow(non_upper_case_globals)] #[no_mangle] -pub static mut stdin: *mut FILE = unsafe { &default_stdin } as *const FILE as *mut FILE; +pub extern "C" fn __stdin() -> *mut FILE { + unsafe { default_stdin.get() } +} -#[allow(non_upper_case_globals)] #[no_mangle] -pub static mut stdout: *mut FILE = unsafe { &default_stdout } as *const FILE as *mut FILE; +pub extern "C" fn __stdout() -> *mut FILE { + unsafe { default_stdout.get() } +} -#[allow(non_upper_case_globals)] #[no_mangle] -pub static mut stderr: *mut FILE = unsafe { &default_stderr } as *const FILE as *mut FILE; +pub extern "C" fn __stderr() -> *mut FILE { + unsafe { default_stderr.get() } +} diff --git a/src/stdio/src/lib.rs b/src/stdio/src/lib.rs index cec2032da6e6b62dc9b9d049fb8123c5e0c64d14..ff4bd1a860c4fabdbef65ac65e22e816a1333c2f 100644 --- a/src/stdio/src/lib.rs +++ b/src/stdio/src/lib.rs @@ -2,6 +2,7 @@ #![no_std] #![feature(alloc)] +#![feature(const_fn)] extern crate alloc; extern crate errno; @@ -619,7 +620,7 @@ pub extern "C" fn getc(stream: &mut FILE) -> c_int { /// Get a single char from `stdin` #[no_mangle] pub unsafe extern "C" fn getchar() -> c_int { - fgetc(&mut *stdin) + fgetc(&mut *__stdin()) } /// Get a char from a stream without locking the stream @@ -644,14 +645,14 @@ pub extern "C" fn getc_unlocked(stream: &mut FILE) -> c_int { /// Get a char from `stdin` without locking `stdin` #[no_mangle] pub unsafe extern "C" fn getchar_unlocked() -> c_int { - getc_unlocked(&mut *stdin) + getc_unlocked(&mut *__stdin()) } /// Get a string from `stdin` #[no_mangle] pub unsafe extern "C" fn gets(s: *mut c_char) -> *mut c_char { use core::i32; - fgets(s, i32::MAX, &mut *stdin) + fgets(s, i32::MAX, &mut *__stdin()) } /// Get an integer from `stream` @@ -706,7 +707,7 @@ pub extern "C" fn putc(c: c_int, stream: &mut FILE) -> c_int { /// Put a character `c` into `stdout` #[no_mangle] pub unsafe extern "C" fn putchar(c: c_int) -> c_int { - fputc(c, &mut *stdout) + fputc(c, &mut *__stdout()) } /// Put a character `c` into `stream` without locking `stream` @@ -738,13 +739,13 @@ pub extern "C" fn putc_unlocked(c: c_int, stream: &mut FILE) -> c_int { /// Put a character `c` into `stdout` without locking `stdout` #[no_mangle] pub unsafe extern "C" fn putchar_unlocked(c: c_int) -> c_int { - putc_unlocked(c, &mut *stdout) + putc_unlocked(c, &mut *__stdout()) } /// Put a string `s` into `stdout` #[no_mangle] pub unsafe extern "C" fn puts(s: *const c_char) -> c_int { - let ret = (fputs(s, &mut *stdout) > 0) || (putchar_unlocked(b'\n' as c_int) > 0); + let ret = (fputs(s, &mut *__stdout()) > 0) || (putchar_unlocked(b'\n' as c_int) > 0); if ret { 0 } else { @@ -872,7 +873,7 @@ pub unsafe extern "C" fn vfprintf(file: &mut FILE, format: *const c_char, ap: va #[no_mangle] pub unsafe extern "C" fn vprintf(format: *const c_char, ap: va_list) -> c_int { - vfprintf(&mut *stdout, format, ap) + vfprintf(&mut *__stdout(), format, ap) } #[no_mangle] @@ -901,7 +902,7 @@ pub unsafe extern "C" fn vfscanf(file: &mut FILE, format: *const c_char, ap: va_ #[no_mangle] pub unsafe extern "C" fn vscanf(format: *const c_char, ap: va_list) -> c_int { - vfscanf(&mut *stdin, format, ap) + vfscanf(&mut *__stdin(), format, ap) } #[no_mangle] diff --git a/src/unistd/src/getopt.rs b/src/unistd/src/getopt.rs index c93a5487b94d3be9ca9e0522811ab028a6b316fb..e1dac2dad77298c515b5f19fe164dd2fb06382c5 100644 --- a/src/unistd/src/getopt.rs +++ b/src/unistd/src/getopt.rs @@ -69,10 +69,10 @@ unsafe fn parse_arg( let print_error = |desc: &[u8]| { // NOTE: we don't use fprintf to get around the usage of va_list - stdio::fputs(*argv as _, &mut *stdio::stderr); - stdio::fputs(desc.as_ptr() as _, &mut *stdio::stderr); - stdio::fputc(*current_arg as _, &mut *stdio::stderr); - stdio::fputc(b'\n' as _, &mut *stdio::stderr); + stdio::fputs(*argv as _, &mut *stdio::__stderr()); + stdio::fputs(desc.as_ptr() as _, &mut *stdio::__stderr()); + stdio::fputc(*current_arg as _, &mut *stdio::__stderr()); + stdio::fputc(b'\n' as _, &mut *stdio::__stderr()); }; match find_option(*current_arg, optstring) {