diff --git a/src/header/stdio/default.rs b/src/header/stdio/default.rs index 90aa709b025c848085fdbe4110debd96f74bcfb4..341d76bd161e870467f89affe3dc5d739e68191e 100644 --- a/src/header/stdio/default.rs +++ b/src/header/stdio/default.rs @@ -2,13 +2,13 @@ use super::{constants, Buffer, BUFSIZ, FILE}; use core::{cell::UnsafeCell, ptr}; use crate::{fs::File, io::LineWriter, platform::types::*, sync::Mutex}; -use alloc::vec::Vec; +use alloc::{boxed::Box, vec::Vec}; pub struct GlobalFile(UnsafeCell<FILE>); impl GlobalFile { fn new(file: c_int, flags: c_int) -> Self { let file = File::new(file); - let writer = LineWriter::new(unsafe { file.get_ref() }); + let writer = Box::new(LineWriter::new(unsafe { file.get_ref() })); GlobalFile(UnsafeCell::new(FILE { lock: Mutex::new(()), diff --git a/src/header/stdio/ext.rs b/src/header/stdio/ext.rs index 28bb73445af4556cb49f21e1d906fb6441c67b43..08aff1b2d2ee6498d953441542860e9b4b9f08b2 100644 --- a/src/header/stdio/ext.rs +++ b/src/header/stdio/ext.rs @@ -7,7 +7,7 @@ use crate::{ pub extern "C" fn __fpending(stream: *mut FILE) -> size_t { let stream = unsafe { &mut *stream }.lock(); - stream.writer.inner.buf.len() as size_t + stream.writer.pending() } #[no_mangle] diff --git a/src/header/stdio/helpers.rs b/src/header/stdio/helpers.rs index be7aa9fa0bb83cd3c203c8aca6d296e4d34ec384..dc42b100158a7002e1d475614bb0edf24adc580e 100644 --- a/src/header/stdio/helpers.rs +++ b/src/header/stdio/helpers.rs @@ -4,7 +4,7 @@ use super::{constants::*, Buffer, FILE}; use crate::{ fs::File, header::{errno, fcntl::*, string::strchr}, - io::LineWriter, + io::BufWriter, platform::{self, types::*}, sync::Mutex, }; @@ -62,7 +62,7 @@ pub unsafe fn _fdopen(fd: c_int, mode: *const c_char) -> Option<*mut FILE> { } let file = File::new(fd); - let writer = LineWriter::new(file.get_ref()); + let writer = Box::new(BufWriter::new(file.get_ref())); Some(Box::into_raw(Box::new(FILE { lock: Mutex::new(()), diff --git a/src/header/stdio/mod.rs b/src/header/stdio/mod.rs index f6625766dda0df5928047a6149a75a949375d619..52bee2737ec5f926028e8ce4303e599cebe7285e 100644 --- a/src/header/stdio/mod.rs +++ b/src/header/stdio/mod.rs @@ -24,7 +24,7 @@ use crate::{ string::{self, strlen}, unistd, }, - io::{self, BufRead, LineWriter, Read, Write}, + io::{self, BufRead, BufWriter, LineWriter, Read, Write}, platform::{self, errno, types::*, Pal, Sys, WriteByte}, sync::Mutex, }; @@ -69,6 +69,27 @@ impl<'a> DerefMut for Buffer<'a> { } } +pub trait Pending { + fn pending(&self) -> size_t; +} + +impl<W: core_io::Write> Pending for BufWriter<W> { + fn pending(&self) -> size_t { + self.buf.len() as size_t + } +} + +impl<W: core_io::Write> Pending for LineWriter<W> { + fn pending(&self) -> size_t { + self.inner.buf.len() as size_t + } +} + +pub trait Writer: Write + Pending {} + +impl<W: core_io::Write> Writer for BufWriter<W> {} +impl<W: core_io::Write> Writer for LineWriter<W> {} + /// This struct gets exposed to the C API. pub struct FILE { lock: Mutex<()>, @@ -81,7 +102,7 @@ pub struct FILE { read_size: usize, unget: Vec<u8>, // pub for stdio_ext - pub(crate) writer: LineWriter<File>, + pub(crate) writer: Box<dyn Writer + Send>, // Optional pid for use with popen/pclose pid: Option<c_int>, @@ -1145,3 +1166,12 @@ pub unsafe extern "C" fn vsscanf(s: *const c_char, format: *const c_char, ap: va let reader = (s as *const u8).into(); scanf::scanf(reader, format, ap) } + +pub unsafe fn flush_io_streams() { + let flush = |stream: *mut FILE| { + let stream = &mut *stream; + stream.flush() + }; + flush(stdout); + flush(stderr); +} diff --git a/src/header/stdlib/mod.rs b/src/header/stdlib/mod.rs index daaf72beaf2659ef38d3f3751ebfc74a205e5708..db708bcebce0bfd75b748ad42b875c7c261d9b01 100644 --- a/src/header/stdlib/mod.rs +++ b/src/header/stdlib/mod.rs @@ -16,6 +16,7 @@ use crate::{ errno::{self, *}, fcntl::*, limits, + stdio::flush_io_streams, string::*, time::constants::CLOCK_MONOTONIC, unistd::{self, sysconf, _SC_PAGESIZE}, @@ -297,6 +298,8 @@ pub unsafe extern "C" fn exit(status: c_int) { pthread_terminate(); + flush_io_streams(); + Sys::exit(status); } diff --git a/tests/expected/wchar/putwchar.stdout b/tests/expected/wchar/putwchar.stdout index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..42d65d1da021231040a6d7e35d1260aa89769751 100644 --- a/tests/expected/wchar/putwchar.stdout +++ b/tests/expected/wchar/putwchar.stdout @@ -0,0 +1 @@ +zß水🌠\ No newline at end of file