Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c6b2128

Browse files
Merge pull request #1030 from joshtriplett/file-eof-should-not-be-permanent
Fix file EOF to not be permanent: reading again should give new data
2 parents 21b72eb + dfdf56c commit c6b2128

File tree

1 file changed

+45
-4
lines changed

1 file changed

+45
-4
lines changed

‎src/fs/file.rs

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -670,14 +670,19 @@ impl LockGuard<State> {
670670

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

677-
// If there is cached unconsumed data or if the cache is empty, we can read from
678-
// it. Empty cache in reading mode indicates that the last operation didn't read
679-
// any bytes, i.e. it reached the end of the file.
680-
if available > 0 || self.cache.is_empty() {
685+
if available > 0 {
681686
// Copy data from the cache into the buffer.
682687
let n = cmp::min(available, buf.len());
683688
buf[..n].copy_from_slice(&self.cache[start..(start + n)]);
@@ -913,4 +918,40 @@ mod tests {
913918
assert_eq!(format!("{}", expect), format!("{}", actual));
914919
})
915920
}
921+
922+
#[test]
923+
fn file_eof_is_not_permanent() -> crate::io::Result<()> {
924+
let tempdir = tempfile::Builder::new()
925+
.prefix("async-std-file-eof-test")
926+
.tempdir()?;
927+
let path = tempdir.path().join("testfile");
928+
929+
crate::task::block_on(async {
930+
let mut file_w = File::create(&path).await?;
931+
let mut file_r = File::open(&path).await?;
932+
933+
file_w.write_all(b"data").await?;
934+
file_w.flush().await?;
935+
936+
let mut buf = [0u8; 4];
937+
let mut len = file_r.read(&mut buf).await?;
938+
assert_eq!(len, 4);
939+
assert_eq!(&buf, b"data");
940+
941+
len = file_r.read(&mut buf).await?;
942+
assert_eq!(len, 0);
943+
944+
file_w.write_all(b"more").await?;
945+
file_w.flush().await?;
946+
947+
len = file_r.read(&mut buf).await?;
948+
assert_eq!(len, 4);
949+
assert_eq!(&buf, b"more");
950+
951+
len = file_r.read(&mut buf).await?;
952+
assert_eq!(len, 0);
953+
954+
Ok(())
955+
})
956+
}
916957
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /