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 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)
96 pub fn is_read_vectored(&self) -> bool {
100 pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
102 let len = cmp::min(buf.len(), <c::DWORD>::MAX as usize) as c::DWORD;
104 let mut overlapped: c::OVERLAPPED = mem::zeroed();
105 overlapped.Offset = offset as u32;
106 overlapped.OffsetHigh = (offset >> 32) as u32;
107 cvt(c::ReadFile(self.0, buf.as_mut_ptr() as c::LPVOID, len, &mut read, &mut overlapped))
110 Ok(_) => Ok(read as usize),
111 Err(ref e) if e.raw_os_error() == Some(c::ERROR_HANDLE_EOF as i32) => Ok(0),
116 pub unsafe fn read_overlapped(
119 overlapped: *mut c::OVERLAPPED,
120 ) -> io::Result<Option<usize>> {
121 let len = cmp::min(buf.len(), <c::DWORD>::MAX as usize) as c::DWORD;
123 let res = cvt(c::ReadFile(self.0, buf.as_ptr() as c::LPVOID, len, &mut amt, overlapped));
125 Ok(_) => Ok(Some(amt as usize)),
127 if e.raw_os_error() == Some(c::ERROR_IO_PENDING as i32) {
129 } else if e.raw_os_error() == Some(c::ERROR_BROKEN_PIPE as i32) {
138 pub fn overlapped_result(
140 overlapped: *mut c::OVERLAPPED,
142 ) -> io::Result<usize> {
145 let wait = if wait { c::TRUE } else { c::FALSE };
146 let res = cvt(c::GetOverlappedResult(self.raw(), overlapped, &mut bytes, wait));
148 Ok(_) => Ok(bytes as usize),
150 if e.raw_os_error() == Some(c::ERROR_HANDLE_EOF as i32)
151 || e.raw_os_error() == Some(c::ERROR_BROKEN_PIPE as i32)
162 pub fn cancel_io(&self) -> io::Result<()> {
163 unsafe { cvt(c::CancelIo(self.raw())).map(drop) }
166 pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
168 let len = cmp::min(buf.len(), <c::DWORD>::MAX as usize) as c::DWORD;
170 c::WriteFile(self.0, buf.as_ptr() as c::LPVOID, len, &mut amt, ptr::null_mut())
175 pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
176 crate::io::default_write_vectored(|buf| self.write(buf), bufs)
180 pub fn is_write_vectored(&self) -> bool {
184 pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
186 let len = cmp::min(buf.len(), <c::DWORD>::MAX as usize) as c::DWORD;
188 let mut overlapped: c::OVERLAPPED = mem::zeroed();
189 overlapped.Offset = offset as u32;
190 overlapped.OffsetHigh = (offset >> 32) as u32;
193 buf.as_ptr() as c::LPVOID,
207 ) -> io::Result<Handle> {
208 let mut ret = 0 as c::HANDLE;
210 let cur_proc = c::GetCurrentProcess();
225 impl<'a> Read for &'a RawHandle {
226 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
230 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
231 (**self).read_vectored(bufs)