use mem;
use path::{Path, PathBuf};
use ptr;
-use rc::Rc;
+use sync::Arc;
use sys::fd::FileDesc;
use sys::{c, cvt, cvt_r};
use sys_common::FromInner;
}
pub struct ReadDir {
- dirp: *mut libc::DIR,
- root: Rc<PathBuf>,
+ dirp: Dir,
+ root: Arc<PathBuf>,
}
+struct Dir(*mut libc::DIR);
+
+unsafe impl Send for Dir {}
+unsafe impl Sync for Dir {}
+
pub struct DirEntry {
- buf: Vec<u8>,
- dirent: *mut libc::dirent_t,
- root: Rc<PathBuf>,
+ buf: Vec<u8>, // actually *mut libc::dirent_t
+ root: Arc<PathBuf>,
}
#[derive(Clone)]
let mut entry_ptr = ptr::null_mut();
loop {
- if unsafe { libc::readdir_r(self.dirp, ptr, &mut entry_ptr) != 0 } {
+ if unsafe { libc::readdir_r(self.dirp.0, ptr, &mut entry_ptr) != 0 } {
return Some(Err(Error::last_os_error()))
}
if entry_ptr.is_null() {
let entry = DirEntry {
buf: buf,
- dirent: entry_ptr,
root: self.root.clone()
};
if entry.name_bytes() == b"." || entry.name_bytes() == b".." {
}
}
-impl Drop for ReadDir {
+impl Drop for Dir {
fn drop(&mut self) {
- let r = unsafe { libc::closedir(self.dirp) };
+ let r = unsafe { libc::closedir(self.0) };
debug_assert_eq!(r, 0);
}
}
fn rust_list_dir_val(ptr: *mut libc::dirent_t) -> *const c_char;
}
unsafe {
- CStr::from_ptr(rust_list_dir_val(self.dirent)).to_bytes()
+ CStr::from_ptr(rust_list_dir_val(self.dirent())).to_bytes()
}
}
+
+ fn dirent(&self) -> *mut libc::dirent_t {
+ self.buf.as_ptr() as *mut _
+ }
}
impl OpenOptions {
}
pub fn readdir(p: &Path) -> io::Result<ReadDir> {
- let root = Rc::new(p.to_path_buf());
+ let root = Arc::new(p.to_path_buf());
let p = try!(cstr(p));
unsafe {
let ptr = libc::opendir(p.as_ptr());
if ptr.is_null() {
Err(Error::last_os_error())
} else {
- Ok(ReadDir { dirp: ptr, root: root })
+ Ok(ReadDir { dirp: Dir(ptr), root: root })
}
}
}