@@ -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