diff --git a/src/header/stdio/mod.rs b/src/header/stdio/mod.rs index e4d3eb1b9e356e286dab9ea91dd42a5067cf7a49..cd9887dd8a9adf364fdc5adf312a41d77e36d7ab 100644 --- a/src/header/stdio/mod.rs +++ b/src/header/stdio/mod.rs @@ -85,10 +85,20 @@ impl<W: core_io::Write> Pending for LineWriter<W> { } } -pub trait Writer: Write + Pending {} +pub trait Writer: Write + Pending { + fn purge(&mut self); +} -impl<W: core_io::Write> Writer for BufWriter<W> {} -impl<W: core_io::Write> Writer for LineWriter<W> {} +impl<W: core_io::Write> Writer for BufWriter<W> { + fn purge(&mut self) { + self.buf.clear(); + } +} +impl<W: core_io::Write> Writer for LineWriter<W> { + fn purge(&mut self) { + self.inner.buf.clear(); + } +} /// This struct gets exposed to the C API. pub struct FILE { @@ -216,6 +226,16 @@ impl FILE { x => Err(x), } } + + pub fn purge(&mut self) { + // Purge read buffer + self.read_pos = 0; + self.read_size = 0; + // Purge unget + self.unget.clear(); + // Purge write buffer + self.writer.purge(); + } } pub struct LockGuard<'a>(&'a mut FILE); @@ -473,6 +493,17 @@ pub unsafe extern "C" fn fopen(filename: *const c_char, mode: *const c_char) -> } } +/// Clear the buffers of a stream +/// Ensure the file is unlocked before calling this function, as it will attempt to lock the file +/// itself. +#[no_mangle] +pub unsafe extern "C" fn __fpurge(stream: *mut FILE) { + if ! stream.is_null() { + let mut stream = (*stream).lock(); + stream.purge(); + } +} + /// Insert a character into the stream #[no_mangle] pub unsafe extern "C" fn fputc(c: c_int, stream: *mut FILE) -> c_int {