diff options
| author | Dan Gohman <dev@sunfishcode.online> | 2021-06-30 21:44:30 -0700 |
|---|---|---|
| committer | Dan Gohman <dev@sunfishcode.online> | 2021-08-19 12:02:39 -0700 |
| commit | d15418586ca78ead4f87ad18fcffa3550c1b169e (patch) | |
| tree | 93234d47e5eab3c9177ad31b9369abcd1c1ed5d1 /library/std/src/sys/windows | |
| parent | 2451f42c1deb9379d5e8e5fa86b0bf857ae048ec (diff) | |
| download | rust-d15418586ca78ead4f87ad18fcffa3550c1b169e.tar.gz rust-d15418586ca78ead4f87ad18fcffa3550c1b169e.zip | |
I/O safety.
Introduce `OwnedFd` and `BorrowedFd`, and the `AsFd` trait, and implementations of `AsFd`, `From<OwnedFd>` and `From<T> for OwnedFd` for relevant types, along with Windows counterparts for handles and sockets. Tracking issue: - <https://github.com/rust-lang/rust/issues/87074> RFC: - <https://github.com/rust-lang/rfcs/blob/master/text/3128-io-safety.md>
Diffstat (limited to 'library/std/src/sys/windows')
| -rw-r--r-- | library/std/src/sys/windows/fs.rs | 73 | ||||
| -rw-r--r-- | library/std/src/sys/windows/handle.rs | 122 | ||||
| -rw-r--r-- | library/std/src/sys/windows/net.rs | 106 | ||||
| -rw-r--r-- | library/std/src/sys/windows/os.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/windows/pipe.rs | 17 | ||||
| -rw-r--r-- | library/std/src/sys/windows/process.rs | 41 | ||||
| -rw-r--r-- | library/std/src/sys/windows/stdio.rs | 21 | ||||
| -rw-r--r-- | library/std/src/sys/windows/thread.rs | 5 |
8 files changed, 248 insertions, 139 deletions
diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs index c677adae688..0c1a50e231c 100644 --- a/library/std/src/sys/windows/fs.rs +++ b/library/std/src/sys/windows/fs.rs @@ -4,6 +4,7 @@ use crate::ffi::OsString; use crate::fmt; use crate::io::{self, Error, IoSlice, IoSliceMut, SeekFrom}; use crate::mem; +use crate::os::windows::io::{AsHandle, BorrowedHandle}; use crate::path::{Path, PathBuf}; use crate::ptr; use crate::slice; @@ -11,7 +12,7 @@ use crate::sync::Arc; use crate::sys::handle::Handle; use crate::sys::time::SystemTime; use crate::sys::{c, cvt}; -use crate::sys_common::FromInner; +use crate::sys_common::{AsInner, FromInner, IntoInner}; use super::to_u16s; @@ -295,12 +296,12 @@ impl File { if handle == c::INVALID_HANDLE_VALUE { Err(Error::last_os_error()) } else { - Ok(File { handle: Handle::new(handle) }) + unsafe { Ok(File { handle: Handle::from_raw_handle(handle) }) } } } pub fn fsync(&self) -> io::Result<()> { - cvt(unsafe { c::FlushFileBuffers(self.handle.raw()) })?; + cvt(unsafe { c::FlushFileBuffers(self.handle.as_raw_handle()) })?; Ok(()) } @@ -313,7 +314,7 @@ impl File { let size = mem::size_of_val(&info); cvt(unsafe { c::SetFileInformationByHandle( - self.handle.raw(), + self.handle.as_raw_handle(), c::FileEndOfFileInfo, &mut info as *mut _ as *mut _, size as c::DWORD, @@ -326,7 +327,7 @@ impl File { pub fn file_attr(&self) -> io::Result<FileAttr> { unsafe { let mut info: c::BY_HANDLE_FILE_INFORMATION = mem::zeroed(); - cvt(c::GetFileInformationByHandle(self.handle.raw(), &mut info))?; + cvt(c::GetFileInformationByHandle(self.handle.as_raw_handle(), &mut info))?; let mut reparse_tag = 0; if info.dwFileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 { let mut b = [0; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; @@ -449,7 +450,7 @@ impl File { }; let pos = pos as c::LARGE_INTEGER; let mut newpos = 0; - cvt(unsafe { c::SetFilePointerEx(self.handle.raw(), pos, &mut newpos, whence) })?; + cvt(unsafe { c::SetFilePointerEx(self.handle.as_raw_handle(), pos, &mut newpos, whence) })?; Ok(newpos as u64) } @@ -457,14 +458,6 @@ impl File { Ok(File { handle: self.handle.duplicate(0, false, c::DUPLICATE_SAME_ACCESS)? }) } - pub fn handle(&self) -> &Handle { - &self.handle - } - - pub fn into_handle(self) -> Handle { - self.handle - } - fn reparse_point<'a>( &self, space: &'a mut [u8; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE], @@ -473,7 +466,7 @@ impl File { let mut bytes = 0; cvt({ c::DeviceIoControl( - self.handle.raw(), + self.handle.as_raw_handle(), c::FSCTL_GET_REPARSE_POINT, ptr::null_mut(), 0, @@ -541,7 +534,7 @@ impl File { let size = mem::size_of_val(&info); cvt(unsafe { c::SetFileInformationByHandle( - self.handle.raw(), + self.handle.as_raw_handle(), c::FileBasicInfo, &mut info as *mut _ as *mut _, size as c::DWORD, @@ -551,9 +544,45 @@ impl File { } } -impl FromInner<c::HANDLE> for File { - fn from_inner(handle: c::HANDLE) -> File { - File { handle: Handle::new(handle) } +impl AsInner<Handle> for File { + fn as_inner(&self) -> &Handle { + &self.handle + } +} + +impl IntoInner<Handle> for File { + fn into_inner(self) -> Handle { + self.handle + } +} + +impl FromInner<Handle> for File { + fn from_inner(handle: Handle) -> File { + File { handle: handle } + } +} + +impl AsHandle for File { + fn as_handle(&self) -> BorrowedHandle<'_> { + self.as_inner().as_handle() + } +} + +impl AsRawHandle for File { + fn as_raw_handle(&self) -> RawHandle { + self.as_inner().as_raw_handle() + } +} + +impl IntoRawHandle for File { + fn into_raw_handle(self) -> RawHandle { + self.into_inner().into_raw_handle() + } +} + +impl FromRawHandle for File { + unsafe fn from_raw_handle(raw_handle: RawHandle) -> Self { + Self { handle: FromInner::from_inner(FromRawHandle::from_raw_handle(raw_handle)) } } } @@ -561,7 +590,7 @@ impl fmt::Debug for File { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // FIXME(#24570): add more info here (e.g., mode) let mut b = f.debug_struct("File"); - b.field("handle", &self.handle.raw()); + b.field("handle", &self.handle.as_raw_handle()); if let Ok(path) = get_path(&self) { b.field("path", &path); } @@ -838,7 +867,7 @@ pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> { fn get_path(f: &File) -> io::Result<PathBuf> { super::fill_utf16_buf( |buf, sz| unsafe { - c::GetFinalPathNameByHandleW(f.handle.raw(), buf, sz, c::VOLUME_NAME_DOS) + c::GetFinalPathNameByHandleW(f.handle.as_raw_handle(), buf, sz, c::VOLUME_NAME_DOS) }, |buf| PathBuf::from(OsString::from_wide(buf)), ) @@ -909,7 +938,7 @@ fn symlink_junction_inner(original: &Path, junction: &Path) -> io::Result<()> { opts.write(true); opts.custom_flags(c::FILE_FLAG_OPEN_REPARSE_POINT | c::FILE_FLAG_BACKUP_SEMANTICS); let f = File::open(junction, &opts)?; - let h = f.handle().raw(); + let h = f.as_inner().as_raw_handle(); unsafe { let mut data = [0u8; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; diff --git a/library/std/src/sys/windows/handle.rs b/library/std/src/sys/windows/handle.rs index 0d4baa3b340..21d86b00226 100644 --- a/library/std/src/sys/windows/handle.rs +++ b/library/std/src/sys/windows/handle.rs @@ -3,76 +3,87 @@ use crate::cmp; use crate::io::{self, ErrorKind, IoSlice, IoSliceMut, Read}; use crate::mem; -use crate::ops::Deref; +use crate::os::windows::io::{ + AsHandle, AsRawHandle, BorrowedHandle, FromRawHandle, IntoRawHandle, OwnedHandle, RawHandle, +}; use crate::ptr; use crate::sys::c; use crate::sys::cvt; +use crate::sys_common::{AsInner, FromInner, IntoInner}; /// An owned container for `HANDLE` object, closing them on Drop. /// /// All methods are inherited through a `Deref` impl to `RawHandle` -pub struct Handle(RawHandle); - -/// A wrapper type for `HANDLE` objects to give them proper Send/Sync inference -/// as well as Rust-y methods. -/// -/// This does **not** drop the handle when it goes out of scope, use `Handle` -/// instead for that. -#[derive(Copy, Clone)] -pub struct RawHandle(c::HANDLE); - -unsafe impl Send for RawHandle {} -unsafe impl Sync for RawHandle {} +pub struct Handle(OwnedHandle); impl Handle { - pub fn new(handle: c::HANDLE) -> Handle { - Handle(RawHandle::new(handle)) - } - pub fn new_event(manual: bool, init: bool) -> io::Result<Handle> { unsafe { let event = c::CreateEventW(ptr::null_mut(), manual as c::BOOL, init as c::BOOL, ptr::null()); - if event.is_null() { Err(io::Error::last_os_error()) } else { Ok(Handle::new(event)) } + if event.is_null() { + Err(io::Error::last_os_error()) + } else { + Ok(Handle::from_raw_handle(event)) + } } } +} - pub fn into_raw(self) -> c::HANDLE { - let ret = self.raw(); - mem::forget(self); - ret +impl AsInner<OwnedHandle> for Handle { + fn as_inner(&self) -> &OwnedHandle { + &self.0 } } -impl Deref for Handle { - type Target = RawHandle; - fn deref(&self) -> &RawHandle { - &self.0 +impl IntoInner<OwnedHandle> for Handle { + fn into_inner(self) -> OwnedHandle { + self.0 } } -impl Drop for Handle { - fn drop(&mut self) { - unsafe { - let _ = c::CloseHandle(self.raw()); - } +impl FromInner<OwnedHandle> for Handle { + fn from_inner(file_desc: OwnedHandle) -> Self { + Self(file_desc) } } -impl RawHandle { - pub fn new(handle: c::HANDLE) -> RawHandle { - RawHandle(handle) +impl AsHandle for Handle { + fn as_handle(&self) -> BorrowedHandle<'_> { + self.0.as_handle() } +} - pub fn raw(&self) -> c::HANDLE { - self.0 +impl AsRawHandle for Handle { + fn as_raw_handle(&self) -> RawHandle { + self.0.as_raw_handle() } +} +impl IntoRawHandle for Handle { + fn into_raw_handle(self) -> RawHandle { + self.0.into_raw_handle() + } +} + +impl FromRawHandle for Handle { + unsafe fn from_raw_handle(raw_handle: RawHandle) -> Self { + Self(FromRawHandle::from_raw_handle(raw_handle)) + } +} + +impl Handle { pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { let mut read = 0; let len = cmp::min(buf.len(), <c::DWORD>::MAX as usize) as c::DWORD; let res = cvt(unsafe { - c::ReadFile(self.0, buf.as_mut_ptr() as c::LPVOID, len, &mut read, ptr::null_mut()) + c::ReadFile( + self.as_raw_handle(), + buf.as_mut_ptr() as c::LPVOID, + len, + &mut read, + ptr::null_mut(), + ) }); match res { @@ -104,7 +115,13 @@ impl RawHandle { let mut overlapped: c::OVERLAPPED = mem::zeroed(); overlapped.Offset = offset as u32; overlapped.OffsetHigh = (offset >> 32) as u32; - cvt(c::ReadFile(self.0, buf.as_mut_ptr() as c::LPVOID, len, &mut read, &mut overlapped)) + cvt(c::ReadFile( + self.as_raw_handle(), + buf.as_mut_ptr() as c::LPVOID, + len, + &mut read, + &mut overlapped, + )) }; match res { Ok(_) => Ok(read as usize), @@ -120,7 +137,13 @@ impl RawHandle { ) -> io::Result<Option<usize>> { let len = cmp::min(buf.len(), <c::DWORD>::MAX as usize) as c::DWORD; let mut amt = 0; - let res = cvt(c::ReadFile(self.0, buf.as_ptr() as c::LPVOID, len, &mut amt, overlapped)); + let res = cvt(c::ReadFile( + self.as_raw_handle(), + buf.as_ptr() as c::LPVOID, + len, + &mut amt, + overlapped, + )); match res { Ok(_) => Ok(Some(amt as usize)), Err(e) => { @@ -143,7 +166,8 @@ impl RawHandle { unsafe { let mut bytes = 0; let wait = if wait { c::TRUE } else { c::FALSE }; - let res = cvt(c::GetOverlappedResult(self.raw(), overlapped, &mut bytes, wait)); + let res = + cvt(c::GetOverlappedResult(self.as_raw_handle(), overlapped, &mut bytes, wait)); match res { Ok(_) => Ok(bytes as usize), Err(e) => { @@ -160,14 +184,20 @@ impl RawHandle { } pub fn cancel_io(&self) -> io::Result<()> { - unsafe { cvt(c::CancelIo(self.raw())).map(drop) } + unsafe { cvt(c::CancelIo(self.as_raw_handle())).map(drop) } } pub fn write(&self, buf: &[u8]) -> io::Result<usize> { let mut amt = 0; let len = cmp::min(buf.len(), <c::DWORD>::MAX as usize) as c::DWORD; cvt(unsafe { - c::WriteFile(self.0, buf.as_ptr() as c::LPVOID, len, &mut amt, ptr::null_mut()) + c::WriteFile( + self.as_raw_handle(), + buf.as_ptr() as c::LPVOID, + len, + &mut amt, + ptr::null_mut(), + ) })?; Ok(amt as usize) } @@ -189,7 +219,7 @@ impl RawHandle { overlapped.Offset = offset as u32; overlapped.OffsetHigh = (offset >> 32) as u32; cvt(c::WriteFile( - self.0, + self.as_raw_handle(), buf.as_ptr() as c::LPVOID, len, &mut written, @@ -210,7 +240,7 @@ impl RawHandle { let cur_proc = c::GetCurrentProcess(); c::DuplicateHandle( cur_proc, - self.0, + self.as_raw_handle(), cur_proc, &mut ret, access, @@ -218,11 +248,11 @@ impl RawHandle { options, ) })?; - Ok(Handle::new(ret)) + unsafe { Ok(Handle::from_raw_handle(ret)) } } } -impl<'a> Read for &'a RawHandle { +impl<'a> Read for &'a Handle { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { (**self).read(buf) } diff --git a/library/std/src/sys/windows/net.rs b/library/std/src/sys/windows/net.rs index 9cea5c5e63a..55aacb38c6f 100644 --- a/library/std/src/sys/windows/net.rs +++ b/library/std/src/sys/windows/net.rs @@ -4,6 +4,9 @@ use crate::cmp; use crate::io::{self, IoSlice, IoSliceMut, Read}; use crate::mem; use crate::net::{Shutdown, SocketAddr}; +use crate::os::windows::io::{ + AsRawSocket, AsSocket, BorrowedSocket, FromRawSocket, IntoRawSocket, OwnedSocket, RawSocket, +}; use crate::ptr; use crate::sync::Once; use crate::sys; @@ -24,7 +27,7 @@ pub mod netc { pub use crate::sys::c::*; } -pub struct Socket(c::SOCKET); +pub struct Socket(OwnedSocket); static INIT: Once = Once::new(); @@ -109,7 +112,7 @@ impl Socket { }; if socket != c::INVALID_SOCKET { - Ok(Self(socket)) + unsafe { Ok(Self::from_raw_socket(socket)) } } else { let error = unsafe { c::WSAGetLastError() }; @@ -124,9 +127,11 @@ impl Socket { return Err(last_error()); } - let socket = Self(socket); - socket.set_no_inherit()?; - Ok(socket) + unsafe { + let socket = Self::from_raw_socket(socket); + socket.set_no_inherit()?; + Ok(socket) + } } } @@ -134,7 +139,7 @@ impl Socket { self.set_nonblocking(true)?; let result = { let (addrp, len) = addr.into_inner(); - let result = unsafe { c::connect(self.0, addrp, len) }; + let result = unsafe { c::connect(self.as_raw_socket(), addrp, len) }; cvt(result).map(drop) }; self.set_nonblocking(false)?; @@ -160,7 +165,7 @@ impl Socket { let fds = { let mut fds = unsafe { mem::zeroed::<c::fd_set>() }; fds.fd_count = 1; - fds.fd_array[0] = self.0; + fds.fd_array[0] = self.as_raw_socket(); fds }; @@ -194,17 +199,19 @@ impl Socket { } pub fn accept(&self, storage: *mut c::SOCKADDR, len: *mut c_int) -> io::Result<Socket> { - let socket = unsafe { c::accept(self.0, storage, len) }; + let socket = unsafe { c::accept(self.as_raw_socket(), storage, len) }; match socket { c::INVALID_SOCKET => Err(last_error()), - _ => Ok(Self(socket)), + _ => unsafe { Ok(Self::from_raw_socket(socket)) }, } } pub fn duplicate(&self) -> io::Result<Socket> { let mut info = unsafe { mem::zeroed::<c::WSAPROTOCOL_INFO>() }; - let result = unsafe { c::WSADuplicateSocketW(self.0, c::GetCurrentProcessId(), &mut info) }; + let result = unsafe { + c::WSADuplicateSocketW(self.as_raw_socket(), c::GetCurrentProcessId(), &mut info) + }; cvt(result)?; let socket = unsafe { c::WSASocketW( @@ -218,7 +225,7 @@ impl Socket { }; if socket != c::INVALID_SOCKET { - Ok(Self(socket)) + unsafe { Ok(Self::from_inner(OwnedSocket::from_raw_socket(socket))) } } else { let error = unsafe { c::WSAGetLastError() }; @@ -241,9 +248,11 @@ impl Socket { return Err(last_error()); } - let socket = Self(socket); - socket.set_no_inherit()?; - Ok(socket) + unsafe { + let socket = Self::from_inner(OwnedSocket::from_raw_socket(socket)); + socket.set_no_inherit()?; + Ok(socket) + } } } @@ -251,7 +260,8 @@ impl Socket { // On unix when a socket is shut down all further reads return 0, so we // do the same on windows to map a shut down socket to returning EOF. let length = cmp::min(buf.len(), i32::MAX as usize) as i32; - let result = unsafe { c::recv(self.0, buf.as_mut_ptr() as *mut _, length, flags) }; + let result = + unsafe { c::recv(self.as_raw_socket(), buf.as_mut_ptr() as *mut _, length, flags) }; match result { c::SOCKET_ERROR => { @@ -279,7 +289,7 @@ impl Socket { let mut flags = 0; let result = unsafe { c::WSARecv( - self.0, + self.as_raw_socket(), bufs.as_mut_ptr() as *mut c::WSABUF, length, &mut nread, @@ -325,7 +335,7 @@ impl Socket { // do the same on windows to map a shut down socket to returning EOF. let result = unsafe { c::recvfrom( - self.0, + self.as_raw_socket(), buf.as_mut_ptr() as *mut _, length, flags, @@ -361,7 +371,7 @@ impl Socket { let mut nwritten = 0; let result = unsafe { c::WSASend( - self.0, + self.as_raw_socket(), bufs.as_ptr() as *const c::WSABUF as *mut _, length, &mut nwritten, @@ -408,8 +418,10 @@ impl Socket { #[cfg(not(target_vendor = "uwp"))] fn set_no_inherit(&self) -> io::Result<()> { - sys::cvt(unsafe { c::SetHandleInformation(self.0 as c::HANDLE, c::HANDLE_FLAG_INHERIT, 0) }) - .map(drop) + sys::cvt(unsafe { + c::SetHandleInformation(self.as_raw_socket() as c::HANDLE, c::HANDLE_FLAG_INHERIT, 0) + }) + .map(drop) } #[cfg(target_vendor = "uwp")] @@ -423,13 +435,14 @@ impl Socket { Shutdown::Read => c::SD_RECEIVE, Shutdown::Both => c::SD_BOTH, }; - let result = unsafe { c::shutdown(self.0, how) }; + let result = unsafe { c::shutdown(self.as_raw_socket(), how) }; cvt(result).map(drop) } pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { let mut nonblocking = nonblocking as c_ulong; - let result = unsafe { c::ioctlsocket(self.0, c::FIONBIO as c_int, &mut nonblocking) }; + let result = + unsafe { c::ioctlsocket(self.as_raw_socket(), c::FIONBIO as c_int, &mut nonblocking) }; cvt(result).map(drop) } @@ -446,6 +459,11 @@ impl Socket { let raw: c_int = net::getsockopt(self, c::SOL_SOCKET, c::SO_ERROR)?; if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) } } + + // This is used by sys_common code to abstract over Windows and Unix. + pub fn as_raw(&self) -> RawSocket { + self.as_inner().as_raw_socket() + } } #[unstable(reason = "not public", issue = "none", feature = "fd_read")] @@ -455,28 +473,44 @@ impl<'a> Read for &'a Socket { } } -impl Drop for Socket { - fn drop(&mut self) { - let _ = unsafe { c::closesocket(self.0) }; +impl AsInner<OwnedSocket> for Socket { + fn as_inner(&self) -> &OwnedSocket { + &self.0 } } -impl AsInner<c::SOCKET> for Socket { - fn as_inner(&self) -> &c::SOCKET { - &self.0 +impl FromInner<OwnedSocket> for Socket { + fn from_inner(sock: OwnedSocket) -> Socket { + Socket(sock) } } -impl FromInner<c::SOCKET> for Socket { - fn from_inner(sock: c::SOCKET) -> Socket { - Socket(sock) +impl IntoInner<OwnedSocket> for Socket { + fn into_inner(self) -> OwnedSocket { + self.0 + } +} + +impl AsSocket for Socket { + fn as_socket(&self) -> BorrowedSocket<'_> { + self.0.as_socket() + } +} + +impl AsRawSocket for Socket { + fn as_raw_socket(&self) -> RawSocket { + self.0.as_raw_socket() + } +} + +impl IntoRawSocket for Socket { + fn into_raw_socket(self) -> RawSocket { + self.0.into_raw_socket() } } -impl IntoInner<c::SOCKET> for Socket { - fn into_inner(self) -> c::SOCKET { - let ret = self.0; - mem::forget(self); - ret +impl FromRawSocket for Socket { + unsafe fn from_raw_socket(raw_socket: RawSocket) -> Self { + Self(FromRawSocket::from_raw_socket(raw_socket)) } } diff --git a/library/std/src/sys/windows/os.rs b/library/std/src/sys/windows/os.rs index 8db97ba50a8..883690c4831 100644 --- a/library/std/src/sys/windows/os.rs +++ b/library/std/src/sys/windows/os.rs @@ -288,7 +288,7 @@ fn home_dir_crt() -> Option<PathBuf> { if c::OpenProcessToken(me, c::TOKEN_READ, &mut token) == 0 { return None; } - let _handle = Handle::new(token); + let _handle = Handle::from_raw_handle(token); super::fill_utf16_buf( |buf, mut sz| { match c::GetUserProfileDirectoryW(token, buf, &mut sz) { diff --git a/library/std/src/sys/windows/pipe.rs b/library/std/src/sys/windows/pipe.rs index 104a8db4659..63d3d6c5ed4 100644 --- a/library/std/src/sys/windows/pipe.rs +++ b/library/std/src/sys/windows/pipe.rs @@ -12,6 +12,7 @@ use crate::sys::c; use crate::sys::fs::{File, OpenOptions}; use crate::sys::handle::Handle; use crate::sys::hashmap_random_keys; +use crate::sys_common::IntoInner; //////////////////////////////////////////////////////////////////////////////// // Anonymous pipes @@ -21,6 +22,12 @@ pub struct AnonPipe { inner: Handle, } +impl IntoInner<Handle> for AnonPipe { + fn into_inner(self) -> Handle { + self.inner + } +} + pub struct Pipes { pub ours: AnonPipe, pub theirs: AnonPipe, @@ -123,7 +130,7 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res } return Err(err); } - ours = Handle::new(handle); + ours = Handle::from_raw_handle(handle); break; } @@ -146,11 +153,11 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res }; opts.security_attributes(&mut sa); let theirs = File::open(Path::new(&name), &opts)?; - let theirs = AnonPipe { inner: theirs.into_handle() }; + let theirs = AnonPipe { inner: theirs.into_inner() }; Ok(Pipes { ours: AnonPipe { inner: ours }, - theirs: AnonPipe { inner: theirs.into_handle() }, + theirs: AnonPipe { inner: theirs.into_inner() }, }) } } @@ -207,7 +214,7 @@ pub fn read2(p1: AnonPipe, v1: &mut Vec<u8>, p2: AnonPipe, v2: &mut Vec<u8>) -> let mut p1 = AsyncPipe::new(p1, v1)?; let mut p2 = AsyncPipe::new(p2, v2)?; - let objs = [p1.event.raw(), p2.event.raw()]; + let objs = [p1.event.as_raw_handle(), p2.event.as_raw_handle()]; // In a loop we wait for either pipe's scheduled read operation to complete. // If the operation completes with 0 bytes, that means EOF was reached, in @@ -262,7 +269,7 @@ impl<'a> AsyncPipe<'a> { // I/O operation is successfully scheduled (what we want). let event = Handle::new_event(true, true)?; let mut overlapped: Box<c::OVERLAPPED> = unsafe { Box::new(mem::zeroed()) }; - overlapped.hEvent = event.raw(); + overlapped.hEvent = event.as_raw_handle(); Ok(AsyncPipe { pipe, overlapped, event, dst, state: State::NotReading }) } diff --git a/library/std/src/sys/windows/process.rs b/library/std/src/sys/windows/process.rs index ae193b82e91..5cfde16faf0 100644 --- a/library/std/src/sys/windows/process.rs +++ b/library/std/src/sys/windows/process.rs @@ -15,6 +15,7 @@ use crate::io::{self, Error, ErrorKind}; use crate::mem; use crate::num::NonZeroI32; use crate::os::windows::ffi::OsStrExt; +use crate::os::windows::io::{AsRawHandle, FromRawHandle}; use crate::path::Path; use crate::ptr; use crate::sys::c; @@ -26,7 +27,7 @@ use crate::sys::pipe::{self, AnonPipe}; use crate::sys::stdio; use crate::sys_common::mutex::StaticMutex; use crate::sys_common::process::{CommandEnv, CommandEnvs}; -use crate::sys_common::AsInner; +use crate::sys_common::{AsInner, IntoInner}; use libc::{c_void, EXIT_FAILURE, EXIT_SUCCESS}; @@ -316,9 +317,9 @@ impl Command { let stdin = stdin.to_handle(c::STD_INPUT_HANDLE, &mut pipes.stdin)?; let stdout = stdout.to_handle(c::STD_OUTPUT_HANDLE, &mut pipes.stdout)?; let stderr = stderr.to_handle(c::STD_ERROR_HANDLE, &mut pipes.stderr)?; - si.hStdInput = stdin.raw(); - si.hStdOutput = stdout.raw(); - si.hStdError = stderr.raw(); + si.hStdInput = stdin.as_raw_handle(); + si.hStdOutput = stdout.as_raw_handle(); + si.hStdError = stderr.as_raw_handle(); unsafe { cvt(c::CreateProcessW( @@ -338,9 +339,11 @@ impl Command { // We close the thread handle because we don't care about keeping // the thread id valid, and we aren't keeping the thread handle // around to be able to close it later. - drop(Handle::new(pi.hThread)); + unsafe { + drop(Handle::from_raw_handle(pi.hThread)); - Ok((Process { handle: Handle::new(pi.hProcess) }, pipes)) + Ok((Process { handle: Handle::from_raw_handle(pi.hProcess) }, pipes)) + } } } @@ -365,13 +368,13 @@ impl Stdio { // should still be unavailable so propagate the // INVALID_HANDLE_VALUE. Stdio::Inherit => match stdio::get_handle(stdio_id) { - Ok(io) => { - let io = Handle::new(io); + Ok(io) => unsafe { + let io = Handle::from_raw_handle(io); let ret = io.duplicate(0, true, c::DUPLICATE_SAME_ACCESS); - io.into_raw(); + io.into_inner(); ret - } - Err(..) => Ok(Handle::new(c::INVALID_HANDLE_VALUE)), + }, + Err(..) => unsafe { Ok(Handle::from_raw_handle(c::INVALID_HANDLE_VALUE)) }, }, Stdio::MakePipe => { @@ -397,7 +400,7 @@ impl Stdio { opts.read(stdio_id == c::STD_INPUT_HANDLE); opts.write(stdio_id != c::STD_INPUT_HANDLE); opts.security_attributes(&mut sa); - File::open(Path::new("NUL"), &opts).map(|file| file.into_handle()) + File::open(Path::new("NUL"), &opts).map(|file| file.into_inner()) } } } @@ -411,7 +414,7 @@ impl From<AnonPipe> for Stdio { impl From<File> for Stdio { fn from(file: File) -> Stdio { - Stdio::Handle(file.into_handle()) + Stdio::Handle(file.into_inner()) } } @@ -430,29 +433,29 @@ pub struct Process { impl Process { pub fn kill(&mut self) -> io::Result<()> { - cvt(unsafe { c::TerminateProcess(self.handle.raw(), 1) })?; + cvt(unsafe { c::TerminateProcess(self.handle.as_raw_handle(), 1) })?; Ok(()) } pub fn id(&self) -> u32 { - unsafe { c::GetProcessId(self.handle.raw()) as u32 } + unsafe { c::GetProcessId(self.handle.as_raw_handle()) as u32 } } pub fn wait(&mut self) -> io::Result<ExitStatus> { unsafe { - let res = c::WaitForSingleObject(self.handle.raw(), c::INFINITE); + let res = c::WaitForSingleObject(self.handle.as_raw_handle(), c::INFINITE); if res != c::WAIT_OBJECT_0 { return Err(Error::last_os_error()); } let mut status = 0; - cvt(c::GetExitCodeProcess(self.handle.raw(), &mut status))?; + cvt(c::GetExitCodeProcess(self.handle.as_raw_handle(), &mut status))?; Ok(ExitStatus(status)) } } pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> { unsafe { - match c::WaitForSingleObject(self.handle.raw(), 0) { + match c::WaitForSingleObject(self.handle.as_raw_handle(), 0) { c::WAIT_OBJECT_0 => {} c::WAIT_TIMEOUT => { return Ok(None); @@ -460,7 +463,7 @@ impl Process { _ => return Err(io::Error::last_os_error()), } let mut status = 0; - cvt(c::GetExitCodeProcess(self.handle.raw(), &mut status))?; + cvt(c::GetExitCodeProcess(self.handle.as_raw_handle(), &mut status))?; Ok(Some(ExitStatus(status))) } } diff --git a/library/std/src/sys/windows/stdio.rs b/library/std/src/sys/windows/stdio.rs index 2973951fe90..1cf0e9f0cf1 100644 --- a/library/std/src/sys/windows/stdio.rs +++ b/library/std/src/sys/windows/stdio.rs @@ -3,6 +3,7 @@ use crate::char::decode_utf16; use crate::cmp; use crate::io; +use crate::os::windows::io::{FromRawHandle, IntoRawHandle}; use crate::ptr; use crate::str; use crate::sys::c; @@ -53,10 +54,12 @@ fn is_console(handle: c::HANDLE) -> bool { fn write(handle_id: c::DWORD, data: &[u8]) -> io::Result<usize> { let handle = get_handle(handle_id)?; if !is_console(handle) { - let handle = Handle::new(handle); - let ret = handle.write(data); - handle.into_raw(); // Don't close the handle - return ret; + unsafe { + let handle = Handle::from_raw_handle(handle); + let ret = handle.write(data); + handle.into_raw_handle(); // Don't close the handle + return ret; + } } // As the console is meant for presenting text, we assume bytes of `data` come from a string @@ -140,10 +143,12 @@ impl io::Read for Stdin { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { let handle = get_handle(c::STD_INPUT_HANDLE)?; if !is_console(handle) { - let handle = Handle::new(handle); - let ret = handle.read(buf); - handle.into_raw(); // Don't close the handle - return ret; + unsafe { + let handle = Handle::from_raw_handle(handle); + let ret = handle.read(buf); + handle.into_raw_handle(); // Don't close the handle + return ret; + } } if buf.len() == 0 { diff --git a/library/std/src/sys/windows/thread.rs b/library/std/src/sys/windows/thread.rs index ef7a9733fd8..a5293133b3a 100644 --- a/library/std/src/sys/windows/thread.rs +++ b/library/std/src/sys/windows/thread.rs @@ -1,6 +1,7 @@ use crate::ffi::CStr; use crate::io; use crate::num::NonZeroUsize; +use crate::os::windows::io::{AsRawHandle, FromRawHandle}; use crate::ptr; use crate::sys::c; use crate::sys::handle::Handle; @@ -45,7 +46,7 @@ impl Thread { drop(Box::from_raw(p)); Err(io::Error::last_os_error()) } else { - Ok(Thread { handle: Handle::new(ret) }) + Ok(Thread { handle: Handle::from_raw_handle(ret) }) }; extern "system" fn thread_start(main: *mut c_void) -> c::DWORD { @@ -71,7 +72,7 @@ impl Thread { } pub fn join(self) { - let rc = unsafe { c::WaitForSingleObject(self.handle.raw(), c::INFINITE) }; + let rc = unsafe { c::WaitForSingleObject(self.handle.as_raw_handle(), c::INFINITE) }; if rc == c::WAIT_FAILED { panic!("failed to join on thread: {}", io::Error::last_os_error()); } |
