@@ -243,17 +243,15 @@ struct InnerReadDir {
243
243
244
244
pub struct ReadDir {
245
245
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
- ) ) ) ]
254
246
end_of_stream : bool ,
255
247
}
256
248
249
+ impl ReadDir {
250
+ fn new ( inner : InnerReadDir ) -> Self {
251
+ Self { inner : Arc :: new ( inner) , end_of_stream : false }
252
+ }
253
+ }
254
+
257
255
struct Dir ( * mut libc:: DIR ) ;
258
256
259
257
unsafe impl Send for Dir { }
@@ -594,6 +592,10 @@ impl Iterator for ReadDir {
594
592
target_os = "illumos"
595
593
) ) ]
596
594
fn next ( & mut self ) -> Option < io:: Result < DirEntry > > {
595
+ if self . end_of_stream {
596
+ return None ;
597
+ }
598
+
597
599
unsafe {
598
600
loop {
599
601
// As of POSIX.1-2017, readdir() is not required to be thread safe; only
@@ -604,8 +606,12 @@ impl Iterator for ReadDir {
604
606
super :: os:: set_errno ( 0 ) ;
605
607
let entry_ptr = readdir64 ( self . inner . dirp . 0 ) ;
606
608
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.
609
615
return match super :: os:: errno ( ) {
610
616
0 => None ,
611
617
e => Some ( Err ( Error :: from_raw_os_error ( e) ) ) ,
@@ -1363,18 +1369,7 @@ pub fn readdir(path: &Path) -> io::Result<ReadDir> {
1363
1369
} else {
1364
1370
let root = path. to_path_buf ( ) ;
1365
1371
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) )
1378
1373
}
1379
1374
}
1380
1375
@@ -1755,7 +1750,6 @@ mod remove_dir_impl {
1755
1750
use crate :: os:: unix:: io:: { AsRawFd , FromRawFd , IntoRawFd } ;
1756
1751
use crate :: os:: unix:: prelude:: { OwnedFd , RawFd } ;
1757
1752
use crate :: path:: { Path , PathBuf } ;
1758
- use crate :: sync:: Arc ;
1759
1753
use crate :: sys:: common:: small_c_string:: run_path_with_cstr;
1760
1754
use crate :: sys:: { cvt, cvt_r} ;
1761
1755
@@ -1827,21 +1821,8 @@ mod remove_dir_impl {
1827
1821
// a valid root is not needed because we do not call any functions involving the full path
1828
1822
// of the DirEntrys.
1829
1823
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) )
1845
1826
}
1846
1827
1847
1828
#[ cfg( any(
0 commit comments