|  | @@ -6,6 +6,7 @@ use alloc::{
 | 
											
												
													
														|  |      vec::Vec,
 |  |      vec::Vec,
 | 
											
												
													
														|  |  };
 |  |  };
 | 
											
												
													
														|  |  use core::{
 |  |  use core::{
 | 
											
												
													
														|  | 
 |  | +    cmp,
 | 
											
												
													
														|  |      ffi::VaList as va_list,
 |  |      ffi::VaList as va_list,
 | 
											
												
													
														|  |      fmt::{self, Write as WriteFmt},
 |  |      fmt::{self, Write as WriteFmt},
 | 
											
												
													
														|  |      mem,
 |  |      mem,
 | 
											
										
											
												
													
														|  | @@ -76,7 +77,7 @@ pub struct FILE {
 | 
											
												
													
														|  |      read_buf: Buffer<'static>,
 |  |      read_buf: Buffer<'static>,
 | 
											
												
													
														|  |      read_pos: usize,
 |  |      read_pos: usize,
 | 
											
												
													
														|  |      read_size: usize,
 |  |      read_size: usize,
 | 
											
												
													
														|  | -    unget: Option<u8>,
 |  | 
 | 
											
												
													
														|  | 
 |  | +    unget: Vec<u8>,
 | 
											
												
													
														|  |      // pub for stdio_ext
 |  |      // pub for stdio_ext
 | 
											
												
													
														|  |      pub(crate) writer: LineWriter<File>,
 |  |      pub(crate) writer: LineWriter<File>,
 | 
											
												
													
														|  |  
 |  |  
 | 
											
										
											
												
													
														|  | @@ -86,11 +87,12 @@ pub struct FILE {
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  impl Read for FILE {
 |  |  impl Read for FILE {
 | 
											
												
													
														|  |      fn read(&mut self, out: &mut [u8]) -> io::Result<usize> {
 |  |      fn read(&mut self, out: &mut [u8]) -> io::Result<usize> {
 | 
											
												
													
														|  | -        if !out.is_empty() {
 |  | 
 | 
											
												
													
														|  | -            if let Some(c) = self.unget.take() {
 |  | 
 | 
											
												
													
														|  | -                out[0] = c;
 |  | 
 | 
											
												
													
														|  | -                return Ok(1);
 |  | 
 | 
											
												
													
														|  | -            }
 |  | 
 | 
											
												
													
														|  | 
 |  | +        let unget_read_size = cmp::min(out.len(), self.unget.len());
 | 
											
												
													
														|  | 
 |  | +        for i in 0..unget_read_size {
 | 
											
												
													
														|  | 
 |  | +            out[i] = self.unget.pop().unwrap();
 | 
											
												
													
														|  | 
 |  | +        }
 | 
											
												
													
														|  | 
 |  | +        if unget_read_size != 0 {
 | 
											
												
													
														|  | 
 |  | +            return Ok(unget_read_size);
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |          let len = {
 |  |          let len = {
 | 
											
										
											
												
													
														|  | @@ -311,11 +313,12 @@ pub unsafe extern "C" fn fgets(
 | 
											
												
													
														|  |      let mut wrote = false;
 |  |      let mut wrote = false;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      if left >= 1 {
 |  |      if left >= 1 {
 | 
											
												
													
														|  | -        if let Some(c) = stream.unget.take() {
 |  | 
 | 
											
												
													
														|  | -            *out = c as c_char;
 |  | 
 | 
											
												
													
														|  | 
 |  | +        let unget_read_size = cmp::min(left, stream.unget.len());
 | 
											
												
													
														|  | 
 |  | +        for _ in 0..unget_read_size {
 | 
											
												
													
														|  | 
 |  | +            *out = stream.unget.pop().unwrap() as i8;
 | 
											
												
													
														|  |              out = out.offset(1);
 |  |              out = out.offset(1);
 | 
											
												
													
														|  | -            left -= 1;
 |  | 
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  | 
 |  | +        left -= unget_read_size;
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      loop {
 |  |      loop {
 | 
											
										
											
												
													
														|  | @@ -533,7 +536,7 @@ pub unsafe extern "C" fn fseeko(stream: *mut FILE, mut off: off_t, whence: c_int
 | 
											
												
													
														|  |      stream.flags &= !(F_EOF | F_ERR);
 |  |      stream.flags &= !(F_EOF | F_ERR);
 | 
											
												
													
														|  |      stream.read_pos = 0;
 |  |      stream.read_pos = 0;
 | 
											
												
													
														|  |      stream.read_size = 0;
 |  |      stream.read_size = 0;
 | 
											
												
													
														|  | -    stream.unget = None;
 |  | 
 | 
											
												
													
														|  | 
 |  | +    stream.unget = Vec::new();
 | 
											
												
													
														|  |      0
 |  |      0
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
										
											
												
													
														|  | @@ -990,11 +993,7 @@ unsafe extern "C" fn tmpnam_inner(buf: *mut c_char, offset: usize) -> *mut c_cha
 | 
											
												
													
														|  |  #[no_mangle]
 |  |  #[no_mangle]
 | 
											
												
													
														|  |  pub unsafe extern "C" fn ungetc(c: c_int, stream: *mut FILE) -> c_int {
 |  |  pub unsafe extern "C" fn ungetc(c: c_int, stream: *mut FILE) -> c_int {
 | 
											
												
													
														|  |      let mut stream = (*stream).lock();
 |  |      let mut stream = (*stream).lock();
 | 
											
												
													
														|  | -    if stream.unget.is_some() {
 |  | 
 | 
											
												
													
														|  | -        platform::errno = errno::EIO;
 |  | 
 | 
											
												
													
														|  | -        return EOF;
 |  | 
 | 
											
												
													
														|  | -    }
 |  | 
 | 
											
												
													
														|  | -    stream.unget = Some(c as u8);
 |  | 
 | 
											
												
													
														|  | 
 |  | +    stream.unget.push(c as u8);
 | 
											
												
													
														|  |      c
 |  |      c
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 |