@@ -19,6 +19,7 @@ use std::libc;
19
19
use std:: mem;
20
20
use std:: rt:: rtio;
21
21
use std:: vec;
22
+ use std:: vec_ng:: Vec ;
22
23
23
24
use io:: { IoResult , retry, keep_going} ;
24
25
@@ -341,7 +342,7 @@ pub fn mkdir(p: &CString, mode: io::FilePermission) -> IoResult<()> {
341
342
342
343
pub fn readdir ( p : & CString ) -> IoResult < ~[ Path ] > {
343
344
use std:: libc:: { dirent_t} ;
344
- use std:: libc:: { opendir, readdir , closedir} ;
345
+ use std:: libc:: { opendir, readdir_r , closedir} ;
345
346
346
347
fn prune ( root : & CString , dirs : ~[ Path ] ) -> ~[ Path ] {
347
348
let root = unsafe { CString :: new ( root. with_ref ( |p| p) , false ) } ;
@@ -353,23 +354,28 @@ pub fn readdir(p: &CString) -> IoResult<~[Path]> {
353
354
}
354
355
355
356
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 ;
357
359
}
358
360
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
+
359
365
debug ! ( "os::list_dir -- BEFORE OPENDIR" ) ;
360
366
361
367
let dir_ptr = p. with_ref ( |buf| unsafe { opendir ( buf) } ) ;
362
368
363
369
if dir_ptr as uint != 0 {
364
370
let mut paths = ~[ ] ;
365
371
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 }
368
375
let cstr = unsafe {
369
376
CString :: new ( rust_list_dir_val ( entry_ptr) , false )
370
377
} ;
371
378
paths. push ( Path :: new ( cstr) ) ;
372
- entry_ptr = unsafe { readdir ( dir_ptr) } ;
373
379
}
374
380
assert_eq ! ( unsafe { closedir( dir_ptr) } , 0 ) ;
375
381
Ok ( prune ( p, paths) )
0 commit comments