1 #![unstable(issue = "none", feature = "windows_handle")]
4 use crate::io::{self, ErrorKind, IoSlice, IoSliceMut, Read};
11 /// An owned container for `HANDLE` object, closing them on Drop.
13 /// All methods are inherited through a `Deref` impl to `RawHandle`
14 pub struct Handle(RawHandle);
16 /// A wrapper type for `HANDLE` objects to give them proper Send/Sync inference
17 /// as well as Rust-y methods.
19 /// This does **not** drop the handle when it goes out of scope, use `Handle`
21 #[derive(Copy, Clone)]
22 pub struct RawHandle(c::HANDLE);
24 unsafe impl Send for RawHandle {}
25 unsafe impl Sync for RawHandle {}
28 pub fn new(handle: c::HANDLE) -> Handle {
29 Handle(RawHandle::new(handle))
32 pub fn new_event(manual: bool, init: bool) -> io::Result<Handle> {
35 c::CreateEventW(ptr::null_mut(), manual as c::BOOL, init as c::BOOL, ptr::null());
36 if event.is_null() { Err(io::Error::last_os_error()) } else { Ok(Handle::new(event)) }
40 pub fn into_raw(self) -> c::HANDLE {
47 impl Deref for Handle {
48 type Target = RawHandle;
49 fn deref(&self) -> &RawHandle {
54 impl Drop for Handle {
57 let _ = c::CloseHandle(self.raw());
63 pub fn new(handle: c::HANDLE) -> RawHandle {
67 pub fn raw(&self) -> c::HANDLE {
71 pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
73 let len = cmp::min(buf.len(), <c::DWORD>::max_value() as usize) as c::DWORD;
74 let res = cvt(unsafe {
75 c::ReadFile(self.0, buf.as_mut_ptr() as c::LPVOID, len, &mut read, ptr::null_mut())
79 Ok(_) => Ok(read as usize),
81 // The special treatment of BrokenPipe is to deal with Windows
82 // pipe semantics, which yields this error when *reading* from
83 // a pipe after the other end has closed; we interpret that as
85 Err(ref e) if e.kind() == ErrorKind::BrokenPipe => Ok(0),
91 pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
92 crate::io::default_read_vectored(|buf| self.read(buf), bufs)
95 pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
97 let len = cmp::min(buf.len(), <c::DWORD>::max_value() as usize) as c::DWORD;
99 let mut overlapped: c::OVERLAPPED = mem::zeroed();
100 overlapped.Offset = offset as u32;
101 overlapped.OffsetHigh = (offset >> 32) as u32;
102 cvt(c::ReadFile(self.0, buf.as_mut_ptr() as c::LPVOID, len, &mut read, &mut overlapped))
105 Ok(_) => Ok(read as usize),
106 Err(ref e) if e.raw_os_error() == Some(c::ERROR_HANDLE_EOF as i32) => Ok(0),
111 pub unsafe fn read_overlapped(
114 overlapped: *mut c::OVERLAPPED,
115 ) -> io::Result<Option<usize>> {
116 let len = cmp::min(buf.len(), <c::DWORD>::max_value() as usize) as c::DWORD;
118 let res = cvt(c::ReadFile(self.0, buf.as_ptr() as c::LPVOID, len, &mut amt, overlapped));
120 Ok(_) => Ok(Some(amt as usize)),
122 if e.raw_os_error() == Some(c::ERROR_IO_PENDING as i32) {
124 } else if e.raw_os_error() == Some(c::ERROR_BROKEN_PIPE as i32) {
133 pub fn overlapped_result(
135 overlapped: *mut c::OVERLAPPED,
137 ) -> io::Result<usize> {
140 let wait = if wait { c::TRUE } else { c::FALSE };
141 let res = cvt(c::GetOverlappedResult(self.raw(), overlapped, &mut bytes, wait));
143 Ok(_) => Ok(bytes as usize),
145 if e.raw_os_error() == Some(c::ERROR_HANDLE_EOF as i32)
146 || e.raw_os_error() == Some(c::ERROR_BROKEN_PIPE as i32)
157 pub fn cancel_io(&self) -> io::Result<()> {
158 unsafe { cvt(c::CancelIo(self.raw())).map(drop) }
161 pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
163 let len = cmp::min(buf.len(), <c::DWORD>::max_value() as usize) as c::DWORD;
165 c::WriteFile(self.0, buf.as_ptr() as c::LPVOID, len, &mut amt, ptr::null_mut())
170 pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
171 crate::io::default_write_vectored(|buf| self.write(buf), bufs)
174 pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
176 let len = cmp::min(buf.len(), <c::DWORD>::max_value() as usize) as c::DWORD;
178 let mut overlapped: c::OVERLAPPED = mem::zeroed();
179 overlapped.Offset = offset as u32;
180 overlapped.OffsetHigh = (offset >> 32) as u32;
183 buf.as_ptr() as c::LPVOID,
197 ) -> io::Result<Handle> {
198 let mut ret = 0 as c::HANDLE;
200 let cur_proc = c::GetCurrentProcess();
215 impl<'a> Read for &'a RawHandle {
216 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
220 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
221 (**self).read_vectored(bufs)