about summary refs log tree commit diff
path: root/src/libnative
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2014-03-04 17:27:43 -0800
committerAlex Crichton <alex@alexcrichton.com>2014-03-05 09:11:10 -0800
commit8334dd445fb10089a68808e7895f0c00d6fd0b3e (patch)
treee6886b691e2cd20d65211444b5993e55076fff2b /src/libnative
parentfe50c75d02c9b41bcda28596077b1122a89bee5d (diff)
downloadrust-8334dd445fb10089a68808e7895f0c00d6fd0b3e.tar.gz
rust-8334dd445fb10089a68808e7895f0c00d6fd0b3e.zip
native: Stop using readdir()
This function is not threadsafe, and is deprecated in favor of the threadsafe
readdir_r variant.

Closes #12692
Diffstat (limited to 'src/libnative')
-rw-r--r--src/libnative/io/file_unix.rs16
1 files changed, 11 insertions, 5 deletions
diff --git a/src/libnative/io/file_unix.rs b/src/libnative/io/file_unix.rs
index 4b6d1813ffa..cf9ada97a32 100644
--- a/src/libnative/io/file_unix.rs
+++ b/src/libnative/io/file_unix.rs
@@ -19,6 +19,7 @@ use std::libc;
 use std::mem;
 use std::rt::rtio;
 use std::vec;
+use std::vec_ng::Vec;
 
 use io::{IoResult, retry, keep_going};
 
@@ -341,7 +342,7 @@ pub fn mkdir(p: &CString, mode: io::FilePermission) -> IoResult<()> {
 
 pub fn readdir(p: &CString) -> IoResult<~[Path]> {
     use std::libc::{dirent_t};
-    use std::libc::{opendir, readdir, closedir};
+    use std::libc::{opendir, readdir_r, closedir};
 
     fn prune(root: &CString, dirs: ~[Path]) -> ~[Path] {
         let root = unsafe { CString::new(root.with_ref(|p| p), false) };
@@ -353,9 +354,14 @@ pub fn readdir(p: &CString) -> IoResult<~[Path]> {
     }
 
     extern {
-        fn rust_list_dir_val(ptr: *dirent_t) -> *libc::c_char;
+        fn rust_dirent_t_size() -> libc::c_int;
+        fn rust_list_dir_val(ptr: *mut dirent_t) -> *libc::c_char;
     }
 
+    let size = unsafe { rust_dirent_t_size() };
+    let mut buf = Vec::<u8>::with_capacity(size as uint);
+    let ptr = buf.as_mut_slice().as_mut_ptr() as *mut dirent_t;
+
     debug!("os::list_dir -- BEFORE OPENDIR");
 
     let dir_ptr = p.with_ref(|buf| unsafe { opendir(buf) });
@@ -363,13 +369,13 @@ pub fn readdir(p: &CString) -> IoResult<~[Path]> {
     if dir_ptr as uint != 0 {
         let mut paths = ~[];
         debug!("os::list_dir -- opendir() SUCCESS");
-        let mut entry_ptr = unsafe { readdir(dir_ptr) };
-        while entry_ptr as uint != 0 {
+        let mut entry_ptr = 0 as *mut dirent_t;
+        while unsafe { readdir_r(dir_ptr, ptr, &mut entry_ptr) == 0 } {
+            if entry_ptr.is_null() { break }
             let cstr = unsafe {
                 CString::new(rust_list_dir_val(entry_ptr), false)
             };
             paths.push(Path::new(cstr));
-            entry_ptr = unsafe { readdir(dir_ptr) };
         }
         assert_eq!(unsafe { closedir(dir_ptr) }, 0);
         Ok(prune(p, paths))