diff options
Diffstat (limited to 'src/libstd/sys/windows')
| -rw-r--r-- | src/libstd/sys/windows/fs2.rs | 39 | ||||
| -rw-r--r-- | src/libstd/sys/windows/mod.rs | 10 | ||||
| -rw-r--r-- | src/libstd/sys/windows/net.rs | 13 | ||||
| -rw-r--r-- | src/libstd/sys/windows/tcp.rs | 2 | ||||
| -rw-r--r-- | src/libstd/sys/windows/tty.rs | 2 |
5 files changed, 46 insertions, 20 deletions
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()) } diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index a756fb29f81..3acb372f658 100644 --- a/src/libstd/sys/windows/mod.rs +++ b/src/libstd/sys/windows/mod.rs @@ -192,12 +192,12 @@ pub fn wouldblock() -> bool { err == libc::WSAEWOULDBLOCK as i32 } -pub fn set_nonblocking(fd: sock_t, nb: bool) -> IoResult<()> { +pub fn set_nonblocking(fd: sock_t, nb: bool) { let mut set = nb as libc::c_ulong; - if unsafe { c::ioctlsocket(fd, c::FIONBIO, &mut set) != 0 } { - Err(last_error()) - } else { - Ok(()) + if unsafe { c::ioctlsocket(fd, c::FIONBIO, &mut set) } != 0 { + // The above function should not return an error unless we passed it + // invalid parameters. Panic on errors. + Err(last_error()).unwrap(); } } diff --git a/src/libstd/sys/windows/net.rs b/src/libstd/sys/windows/net.rs index 3451232f40a..6caa4df5dfe 100644 --- a/src/libstd/sys/windows/net.rs +++ b/src/libstd/sys/windows/net.rs @@ -25,6 +25,8 @@ pub type wrlen_t = i32; pub struct Socket(libc::SOCKET); +/// Checks whether the Windows socket interface has been started already, and +/// if not, starts it. pub fn init() { static START: Once = ONCE_INIT; @@ -38,10 +40,16 @@ pub fn init() { }); } +/// Returns the last error from the Windows socket interface. fn last_error() -> io::Error { io::Error::from_os_error(unsafe { c::WSAGetLastError() }) } +/// Checks if the signed integer is the Windows constant `SOCKET_ERROR` (-1) +/// and if so, returns the last error from the Windows socket interface. . This +/// function must be called before another call to the socket API is made. +/// +/// FIXME: generics needed? pub fn cvt<T: SignedInt>(t: T) -> io::Result<T> { let one: T = Int::one(); if t == -one { @@ -51,11 +59,14 @@ pub fn cvt<T: SignedInt>(t: T) -> io::Result<T> { } } +/// Provides the functionality of `cvt` for the return values of `getaddrinfo` +/// and similar, meaning that they return an error if the return value is 0. pub fn cvt_gai(err: c_int) -> io::Result<()> { if err == 0 { return Ok(()) } cvt(err).map(|_| ()) } +/// Provides the functionality of `cvt` for a closure. pub fn cvt_r<T: SignedInt, F>(mut f: F) -> io::Result<T> where F: FnMut() -> T { cvt(f()) } @@ -112,7 +123,7 @@ impl Socket { impl Drop for Socket { fn drop(&mut self) { - unsafe { let _ = libc::closesocket(self.0); } + unsafe { cvt(libc::closesocket(self.0)).unwrap(); } } } diff --git a/src/libstd/sys/windows/tcp.rs b/src/libstd/sys/windows/tcp.rs index 4804ca510cb..25b70918591 100644 --- a/src/libstd/sys/windows/tcp.rs +++ b/src/libstd/sys/windows/tcp.rs @@ -192,7 +192,7 @@ impl TcpAcceptor { c::WSAEventSelect(socket, events[1], 0) }; if ret != 0 { return Err(last_net_error()) } - try!(set_nonblocking(socket, false)); + set_nonblocking(socket, false); return Ok(stream) } } diff --git a/src/libstd/sys/windows/tty.rs b/src/libstd/sys/windows/tty.rs index 8a8b5309057..c9bac69c434 100644 --- a/src/libstd/sys/windows/tty.rs +++ b/src/libstd/sys/windows/tty.rs @@ -52,7 +52,7 @@ fn invalid_encoding() -> IoError { pub fn is_tty(fd: c_int) -> bool { let mut out: DWORD = 0; - // If this function doesn't panic then fd is a TTY + // If this function doesn't return an error, then fd is a TTY match unsafe { GetConsoleMode(get_osfhandle(fd) as HANDLE, &mut out as LPDWORD) } { 0 => false, |
