@@ -34,6 +34,17 @@ use libc::c_char;
3434use libc:: dirfd;
3535#[ cfg( any( target_os = "linux" , target_os = "emscripten" ) ) ]
3636use libc:: fstatat64;
37+ #[ cfg( any(
38+ target_os = "solaris" ,
39+ target_os = "fuchsia" ,
40+ target_os = "redox" ,
41+ target_os = "illumos"
42+ ) ) ]
43+ use libc:: readdir as readdir64;
44+ #[ cfg( target_os = "linux" ) ]
45+ use libc:: readdir64;
46+ #[ cfg( any( target_os = "emscripten" , target_os = "l4re" ) ) ]
47+ use libc:: readdir64_r;
3748#[ cfg( not( any(
3849 target_os = "linux" ,
3950 target_os = "emscripten" ,
@@ -60,9 +71,7 @@ use libc::{
6071 lstat as lstat64, off_t as off64_t, open as open64, stat as stat64,
6172} ;
6273#[ cfg( any( target_os = "linux" , target_os = "emscripten" , target_os = "l4re" ) ) ]
63- use libc:: {
64- dirent64, fstat64, ftruncate64, lseek64, lstat64, off64_t, open64, readdir64_r, stat64,
65- } ;
74+ use libc:: { dirent64, fstat64, ftruncate64, lseek64, lstat64, off64_t, open64, stat64} ;
6675
6776pub use crate :: sys_common:: fs:: { remove_dir_all, try_exists} ;
6877
@@ -202,6 +211,7 @@ struct InnerReadDir {
202211pub struct ReadDir {
203212 inner : Arc < InnerReadDir > ,
204213 #[ cfg( not( any(
214+ target_os = "linux" ,
205215 target_os = "solaris" ,
206216 target_os = "illumos" ,
207217 target_os = "fuchsia" ,
@@ -223,12 +233,13 @@ pub struct DirEntry {
223233 // array to store the name, b) its lifetime between readdir
224234 // calls is not guaranteed.
225235 #[ cfg( any(
236+ target_os = "linux" ,
226237 target_os = "solaris" ,
227238 target_os = "illumos" ,
228239 target_os = "fuchsia" ,
229240 target_os = "redox"
230241 ) ) ]
231- name : Box < [ u8 ] > ,
242+ name : Box < CStr > ,
232243}
233244
234245#[ derive( Clone , Debug ) ]
@@ -449,22 +460,21 @@ impl Iterator for ReadDir {
449460 type Item = io:: Result < DirEntry > ;
450461
451462 #[ cfg( any(
463+ target_os = "linux" ,
452464 target_os = "solaris" ,
453465 target_os = "fuchsia" ,
454466 target_os = "redox" ,
455467 target_os = "illumos"
456468 ) ) ]
457469 fn next ( & mut self ) -> Option < io:: Result < DirEntry > > {
458- use crate :: slice;
459-
460470 unsafe {
461471 loop {
462472 // Although readdir_r(3) would be a correct function to use here because
463473 // of the thread safety, on Illumos and Fuchsia the readdir(3C) function
464474 // is safe to use in threaded applications and it is generally preferred
465475 // over the readdir_r(3C) function.
466476 super :: os:: set_errno ( 0 ) ;
467- let entry_ptr = libc :: readdir ( self . inner . dirp . 0 ) ;
477+ let entry_ptr = readdir64 ( self . inner . dirp . 0 ) ;
468478 if entry_ptr. is_null ( ) {
469479 // null can mean either the end is reached or an error occurred.
470480 // So we had to clear errno beforehand to check for an error now.
@@ -475,14 +485,11 @@ impl Iterator for ReadDir {
475485 }
476486
477487 let name = ( * entry_ptr) . d_name . as_ptr ( ) ;
478- let namelen = libc:: strlen ( name) as usize ;
479488
480489 let ret = DirEntry {
481490 entry : * entry_ptr,
482- name : slice:: from_raw_parts ( name as * const u8 , namelen as usize )
483- . to_owned ( )
484- . into_boxed_slice ( ) ,
485491 dir : Arc :: clone ( & self . inner ) ,
492+ name : CStr :: from_ptr ( name) . into ( ) ,
486493 } ;
487494 if ret. name_bytes ( ) != b"." && ret. name_bytes ( ) != b".." {
488495 return Some ( Ok ( ret) ) ;
@@ -492,6 +499,7 @@ impl Iterator for ReadDir {
492499 }
493500
494501 #[ cfg( not( any(
502+ target_os = "linux" ,
495503 target_os = "solaris" ,
496504 target_os = "fuchsia" ,
497505 target_os = "redox" ,
@@ -547,7 +555,7 @@ impl DirEntry {
547555 #[ cfg( any( target_os = "linux" , target_os = "emscripten" , target_os = "android" ) ) ]
548556 pub fn metadata ( & self ) -> io:: Result < FileAttr > {
549557 let fd = cvt ( unsafe { dirfd ( self . dir . dirp . 0 ) } ) ?;
550- let name = self . entry . d_name . as_ptr ( ) ;
558+ let name = self . name . as_ptr ( ) ;
551559
552560 cfg_has_statx ! {
553561 if let Some ( ret) = unsafe { try_statx(
@@ -647,7 +655,6 @@ impl DirEntry {
647655 }
648656 #[ cfg( any(
649657 target_os = "android" ,
650- target_os = "linux" ,
651658 target_os = "emscripten" ,
652659 target_os = "l4re" ,
653660 target_os = "haiku" ,
@@ -658,13 +665,14 @@ impl DirEntry {
658665 unsafe { CStr :: from_ptr ( self . entry . d_name . as_ptr ( ) ) . to_bytes ( ) }
659666 }
660667 #[ cfg( any(
668+ target_os = "linux" ,
661669 target_os = "solaris" ,
662670 target_os = "illumos" ,
663671 target_os = "fuchsia" ,
664672 target_os = "redox"
665673 ) ) ]
666674 fn name_bytes ( & self ) -> & [ u8 ] {
667- & * self . name
675+ self . name . to_bytes ( )
668676 }
669677
670678 pub fn file_name_os_str ( & self ) -> & OsStr {
@@ -1068,6 +1076,7 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
10681076 Ok ( ReadDir {
10691077 inner : Arc :: new ( inner) ,
10701078 #[ cfg( not( any(
1079+ target_os = "linux" ,
10711080 target_os = "solaris" ,
10721081 target_os = "illumos" ,
10731082 target_os = "fuchsia" ,
0 commit comments