@@ -243,17 +243,15 @@ struct InnerReadDir {
243243
244244pub struct ReadDir {
245245 inner : Arc < InnerReadDir > ,
246- #[ cfg( not( any(
247- target_os = "android" ,
248- target_os = "linux" ,
249- target_os = "solaris" ,
250- target_os = "illumos" ,
251- target_os = "fuchsia" ,
252- target_os = "redox" ,
253- ) ) ) ]
254246 end_of_stream : bool ,
255247}
256248
249+ impl ReadDir {
250+ fn new ( inner : InnerReadDir ) -> Self {
251+ Self { inner : Arc :: new ( inner) , end_of_stream : false }
252+ }
253+ }
254+
257255struct Dir ( * mut libc:: DIR ) ;
258256
259257unsafe impl Send for Dir { }
@@ -594,6 +592,10 @@ impl Iterator for ReadDir {
594592 target_os = "illumos"
595593 ) ) ]
596594 fn next ( & mut self ) -> Option < io:: Result < DirEntry > > {
595+ if self . end_of_stream {
596+ return None ;
597+ }
598+
597599 unsafe {
598600 loop {
599601 // As of POSIX.1-2017, readdir() is not required to be thread safe; only
@@ -604,8 +606,12 @@ impl Iterator for ReadDir {
604606 super :: os:: set_errno ( 0 ) ;
605607 let entry_ptr = readdir64 ( self . inner . dirp . 0 ) ;
606608 if entry_ptr. is_null ( ) {
607- // null can mean either the end is reached or an error occurred.
608- // So we had to clear errno beforehand to check for an error now.
609+ // We either encountered an error, or reached the end. Either way,
610+ // the next call to next() should return None.
611+ self . end_of_stream = true ;
612+
613+ // To distinguish between errors and end-of-directory, we had to clear
614+ // errno beforehand to check for an error now.
609615 return match super :: os:: errno ( ) {
610616 0 => None ,
611617 e => Some ( Err ( Error :: from_raw_os_error ( e) ) ) ,
@@ -1363,18 +1369,7 @@ pub fn readdir(path: &Path) -> io::Result<ReadDir> {
13631369 } else {
13641370 let root = path. to_path_buf ( ) ;
13651371 let inner = InnerReadDir { dirp : Dir ( ptr) , root } ;
1366- Ok ( ReadDir {
1367- inner : Arc :: new ( inner) ,
1368- #[ cfg( not( any(
1369- target_os = "android" ,
1370- target_os = "linux" ,
1371- target_os = "solaris" ,
1372- target_os = "illumos" ,
1373- target_os = "fuchsia" ,
1374- target_os = "redox" ,
1375- ) ) ) ]
1376- end_of_stream : false ,
1377- } )
1372+ Ok ( ReadDir :: new ( inner) )
13781373 }
13791374}
13801375
@@ -1755,7 +1750,6 @@ mod remove_dir_impl {
17551750 use crate :: os:: unix:: io:: { AsRawFd , FromRawFd , IntoRawFd } ;
17561751 use crate :: os:: unix:: prelude:: { OwnedFd , RawFd } ;
17571752 use crate :: path:: { Path , PathBuf } ;
1758- use crate :: sync:: Arc ;
17591753 use crate :: sys:: common:: small_c_string:: run_path_with_cstr;
17601754 use crate :: sys:: { cvt, cvt_r} ;
17611755
@@ -1827,21 +1821,8 @@ mod remove_dir_impl {
18271821 // a valid root is not needed because we do not call any functions involving the full path
18281822 // of the DirEntrys.
18291823 let dummy_root = PathBuf :: new ( ) ;
1830- Ok ( (
1831- ReadDir {
1832- inner : Arc :: new ( InnerReadDir { dirp, root : dummy_root } ) ,
1833- #[ cfg( not( any(
1834- target_os = "android" ,
1835- target_os = "linux" ,
1836- target_os = "solaris" ,
1837- target_os = "illumos" ,
1838- target_os = "fuchsia" ,
1839- target_os = "redox" ,
1840- ) ) ) ]
1841- end_of_stream : false ,
1842- } ,
1843- new_parent_fd,
1844- ) )
1824+ let inner = InnerReadDir { dirp, root : dummy_root } ;
1825+ Ok ( ( ReadDir :: new ( inner) , new_parent_fd) )
18451826 }
18461827
18471828 #[ cfg( any(
0 commit comments