Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 45 additions & 4 deletions src/fs/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -670,14 +670,19 @@ impl LockGuard<State> {

match self.mode {
Mode::Idle => {}
Mode::Reading(0) if self.cache.is_empty() => {
// If the cache is empty in reading mode, the last operation didn't read any bytes,
// which indicates that it reached the end of the file. In this case we need to
// reset the mode to idle so that next time we try to read again, since the file
// may grow after the first EOF.
self.mode = Mode::Idle;
return Poll::Ready(Ok(0));
}
Mode::Reading(start) => {
// How many bytes in the cache are available for reading.
let available = self.cache.len() - start;

// If there is cached unconsumed data or if the cache is empty, we can read from
// it. Empty cache in reading mode indicates that the last operation didn't read
// any bytes, i.e. it reached the end of the file.
if available > 0 || self.cache.is_empty() {
if available > 0 {
// Copy data from the cache into the buffer.
let n = cmp::min(available, buf.len());
buf[..n].copy_from_slice(&self.cache[start..(start + n)]);
Expand Down Expand Up @@ -913,4 +918,40 @@ mod tests {
assert_eq!(format!("{}", expect), format!("{}", actual));
})
}

#[test]
fn file_eof_is_not_permanent() -> crate::io::Result<()> {
let tempdir = tempfile::Builder::new()
.prefix("async-std-file-eof-test")
.tempdir()?;
let path = tempdir.path().join("testfile");

crate::task::block_on(async {
let mut file_w = File::create(&path).await?;
let mut file_r = File::open(&path).await?;

file_w.write_all(b"data").await?;
file_w.flush().await?;

let mut buf = [0u8; 4];
let mut len = file_r.read(&mut buf).await?;
assert_eq!(len, 4);
assert_eq!(&buf, b"data");

len = file_r.read(&mut buf).await?;
assert_eq!(len, 0);

file_w.write_all(b"more").await?;
file_w.flush().await?;

len = file_r.read(&mut buf).await?;
assert_eq!(len, 4);
assert_eq!(&buf, b"more");

len = file_r.read(&mut buf).await?;
assert_eq!(len, 0);

Ok(())
})
}
}