@@ -19,6 +19,7 @@ use std::libc;
1919use std:: mem;
2020use std:: rt:: rtio;
2121use std:: vec;
22+ use std:: vec_ng:: Vec ;
2223
2324use io:: { IoResult , retry, keep_going} ;
2425
@@ -341,7 +342,7 @@ pub fn mkdir(p: &CString, mode: io::FilePermission) -> IoResult<()> {
341342
342343pub fn readdir ( p : & CString ) -> IoResult < ~[ Path ] > {
343344 use std:: libc:: { dirent_t} ;
344- use std:: libc:: { opendir, readdir , closedir} ;
345+ use std:: libc:: { opendir, readdir_r , closedir} ;
345346
346347 fn prune ( root : & CString , dirs : ~[ Path ] ) -> ~[ Path ] {
347348 let root = unsafe { CString :: new ( root. with_ref ( |p| p) , false ) } ;
@@ -353,23 +354,28 @@ pub fn readdir(p: &CString) -> IoResult<~[Path]> {
353354 }
354355
355356 extern {
356- fn rust_list_dir_val ( ptr : * dirent_t ) -> * libc:: c_char ;
357+ fn rust_dirent_t_size ( ) -> libc:: c_int ;
358+ fn rust_list_dir_val ( ptr : * mut dirent_t ) -> * libc:: c_char ;
357359 }
358360
361+ let size = unsafe { rust_dirent_t_size ( ) } ;
362+ let mut buf = Vec :: < u8 > :: with_capacity ( size as uint ) ;
363+ let ptr = buf. as_mut_slice ( ) . as_mut_ptr ( ) as * mut dirent_t ;
364+
359365 debug ! ( "os::list_dir -- BEFORE OPENDIR" ) ;
360366
361367 let dir_ptr = p. with_ref ( |buf| unsafe { opendir ( buf) } ) ;
362368
363369 if dir_ptr as uint != 0 {
364370 let mut paths = ~[ ] ;
365371 debug ! ( "os::list_dir -- opendir() SUCCESS" ) ;
366- let mut entry_ptr = unsafe { readdir ( dir_ptr) } ;
367- while entry_ptr as uint != 0 {
372+ let mut entry_ptr = 0 as * mut dirent_t ;
373+ while unsafe { readdir_r ( dir_ptr, ptr, & mut entry_ptr) == 0 } {
374+ if entry_ptr. is_null ( ) { break }
368375 let cstr = unsafe {
369376 CString :: new ( rust_list_dir_val ( entry_ptr) , false )
370377 } ;
371378 paths. push ( Path :: new ( cstr) ) ;
372- entry_ptr = unsafe { readdir ( dir_ptr) } ;
373379 }
374380 assert_eq ! ( unsafe { closedir( dir_ptr) } , 0 ) ;
375381 Ok ( prune ( p, paths) )
0 commit comments