diff options
| author | Manish Goregaokar <manishsmail@gmail.com> | 2015-02-24 07:17:28 +0530 |
|---|---|---|
| committer | Manish Goregaokar <manishsmail@gmail.com> | 2015-02-24 12:08:36 +0530 |
| commit | 54041c2711c1c0931ca7a58da1119ea53dd90140 (patch) | |
| tree | 85abe5afe82cdbfd6d00671caa4d0ada5c822783 /src/libstd/sys | |
| parent | d7df3533777882a1081451493031162c8c2d5538 (diff) | |
| parent | 756210a0b95f807e95189f1c608d8343ad68e66d (diff) | |
| download | rust-54041c2711c1c0931ca7a58da1119ea53dd90140.tar.gz rust-54041c2711c1c0931ca7a58da1119ea53dd90140.zip | |
Rollup merge of #22594 - alexcrichton:issue-22577, r=aturon
The windows/unix modules were currently inconsistent about the traits being implemented for `DirEntry` and there isn't much particular reason why the traits *couldn't* be implemented for `ReadDir` and `DirEntry`, so this commit ensures that they are implemented. Closes #22577
Diffstat (limited to 'src/libstd/sys')
| -rw-r--r-- | src/libstd/sys/unix/fs2.rs | 33 | ||||
| -rw-r--r-- | src/libstd/sys/windows/fs2.rs | 39 |
2 files changed, 47 insertions, 25 deletions
diff --git a/src/libstd/sys/unix/fs2.rs b/src/libstd/sys/unix/fs2.rs index 92a47c6c385..c6b9c2cba52 100644 --- a/src/libstd/sys/unix/fs2.rs +++ b/src/libstd/sys/unix/fs2.rs @@ -18,7 +18,7 @@ use libc::{self, c_int, c_void, size_t, off_t, c_char, mode_t}; 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; @@ -31,14 +31,18 @@ pub struct FileAttr { } 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)] @@ -109,7 +113,7 @@ impl Iterator for ReadDir { 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() { @@ -118,7 +122,6 @@ impl Iterator for ReadDir { let entry = DirEntry { buf: buf, - dirent: entry_ptr, root: self.root.clone() }; if entry.name_bytes() == b"." || entry.name_bytes() == b".." { @@ -130,9 +133,9 @@ impl Iterator for ReadDir { } } -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); } } @@ -147,9 +150,13 @@ impl DirEntry { 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 { @@ -279,14 +286,14 @@ pub fn mkdir(p: &Path) -> io::Result<()> { } 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 }) } } } diff --git a/src/libstd/sys/windows/fs2.rs b/src/libstd/sys/windows/fs2.rs index 8abcd90efe8..117f819eeeb 100644 --- a/src/libstd/sys/windows/fs2.rs +++ b/src/libstd/sys/windows/fs2.rs @@ -19,6 +19,7 @@ use libc::{self, HANDLE}; use mem; use path::{Path, PathBuf}; use ptr; +use sync::Arc; use sys::handle::Handle as RawHandle; use sys::{c, cvt}; use vec::Vec; @@ -27,12 +28,20 @@ pub struct File { handle: RawHandle } pub struct FileAttr { data: c::WIN32_FILE_ATTRIBUTE_DATA } pub struct ReadDir { - handle: libc::HANDLE, - root: PathBuf, + handle: FindNextFileHandle, + root: Arc<PathBuf>, first: Option<libc::WIN32_FIND_DATAW>, } -pub struct DirEntry { path: PathBuf } +struct FindNextFileHandle(libc::HANDLE); + +unsafe impl Send for FindNextFileHandle {} +unsafe impl Sync for FindNextFileHandle {} + +pub struct DirEntry { + root: Arc<PathBuf>, + data: libc::WIN32_FIND_DATAW, +} #[derive(Clone, Default)] pub struct OpenOptions { @@ -61,7 +70,7 @@ impl Iterator for ReadDir { unsafe { let mut wfd = mem::zeroed(); loop { - if libc::FindNextFileW(self.handle, &mut wfd) == 0 { + if libc::FindNextFileW(self.handle.0, &mut wfd) == 0 { if libc::GetLastError() == c::ERROR_NO_MORE_FILES as libc::DWORD { return None @@ -77,15 +86,15 @@ impl Iterator for ReadDir { } } -impl Drop for ReadDir { +impl Drop for FindNextFileHandle { fn drop(&mut self) { - let r = unsafe { libc::FindClose(self.handle) }; + let r = unsafe { libc::FindClose(self.0) }; debug_assert!(r != 0); } } impl DirEntry { - fn new(root: &Path, wfd: &libc::WIN32_FIND_DATAW) -> Option<DirEntry> { + fn new(root: &Arc<PathBuf>, wfd: &libc::WIN32_FIND_DATAW) -> Option<DirEntry> { match &wfd.cFileName[0..3] { // check for '.' and '..' [46, 0, ..] | @@ -93,13 +102,15 @@ impl DirEntry { _ => {} } - let filename = super::truncate_utf16_at_nul(&wfd.cFileName); - let filename: OsString = OsStringExt::from_wide(filename); - Some(DirEntry { path: root.join(&filename) }) + Some(DirEntry { + root: root.clone(), + data: *wfd, + }) } pub fn path(&self) -> PathBuf { - self.path.clone() + let filename = super::truncate_utf16_at_nul(&self.data.cFileName); + self.root.join(&<OsString as OsStringExt>::from_wide(filename)) } } @@ -312,7 +323,11 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> { let mut wfd = mem::zeroed(); let find_handle = libc::FindFirstFileW(path.as_ptr(), &mut wfd); if find_handle != libc::INVALID_HANDLE_VALUE { - Ok(ReadDir { handle: find_handle, root: root, first: Some(wfd) }) + Ok(ReadDir { + handle: FindNextFileHandle(find_handle), + root: Arc::new(root), + first: Some(wfd), + }) } else { Err(Error::last_os_error()) } |
