From cc0ac982c4dd407213500db8b44fbd501b9ce5ce Mon Sep 17 00:00:00 2001
From: Jeremy Soller <jackpot51@gmail.com>
Date: Fri, 10 Mar 2023 08:37:54 -0700
Subject: [PATCH] Implement __fpurge

---
 src/header/stdio/mod.rs | 37 ++++++++++++++++++++++++++++++++++---
 1 file changed, 34 insertions(+), 3 deletions(-)

diff --git a/src/header/stdio/mod.rs b/src/header/stdio/mod.rs
index e4d3eb1b9..cd9887dd8 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 {
-- 
GitLab