]> git.proxmox.com Git - rustc.git/blame - src/libstd/sys/windows/handle.rs
New upstream version 1.44.1+dfsg1
[rustc.git] / src / libstd / sys / windows / handle.rs
CommitLineData
dfeec247 1#![unstable(issue = "none", feature = "windows_handle")]
54a0048b 2
532ac7d7 3use crate::cmp;
60c5eb7d 4use crate::io::{self, ErrorKind, IoSlice, IoSliceMut, Read};
532ac7d7
XL
5use crate::mem;
6use crate::ops::Deref;
7use crate::ptr;
8use crate::sys::c;
9use crate::sys::cvt;
85aaf69f 10
62682a34
SL
11/// An owned container for `HANDLE` object, closing them on Drop.
12///
13/// All methods are inherited through a `Deref` impl to `RawHandle`
14pub struct Handle(RawHandle);
85aaf69f 15
62682a34
SL
16/// A wrapper type for `HANDLE` objects to give them proper Send/Sync inference
17/// as well as Rust-y methods.
18///
19/// This does **not** drop the handle when it goes out of scope, use `Handle`
20/// instead for that.
21#[derive(Copy, Clone)]
92a42be0 22pub struct RawHandle(c::HANDLE);
62682a34
SL
23
24unsafe impl Send for RawHandle {}
25unsafe impl Sync for RawHandle {}
85aaf69f
SL
26
27impl Handle {
92a42be0 28 pub fn new(handle: c::HANDLE) -> Handle {
62682a34 29 Handle(RawHandle::new(handle))
85aaf69f
SL
30 }
31
54a0048b
SL
32 pub fn new_event(manual: bool, init: bool) -> io::Result<Handle> {
33 unsafe {
60c5eb7d
XL
34 let event =
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)) }
54a0048b
SL
37 }
38 }
39
92a42be0 40 pub fn into_raw(self) -> c::HANDLE {
62682a34 41 let ret = self.raw();
bd371182 42 mem::forget(self);
e74abb32 43 ret
c34b1796 44 }
62682a34
SL
45}
46
47impl Deref for Handle {
48 type Target = RawHandle;
60c5eb7d
XL
49 fn deref(&self) -> &RawHandle {
50 &self.0
51 }
62682a34
SL
52}
53
54impl Drop for Handle {
55 fn drop(&mut self) {
60c5eb7d
XL
56 unsafe {
57 let _ = c::CloseHandle(self.raw());
58 }
62682a34
SL
59 }
60}
61
62impl RawHandle {
92a42be0 63 pub fn new(handle: c::HANDLE) -> RawHandle {
62682a34
SL
64 RawHandle(handle)
65 }
66
60c5eb7d
XL
67 pub fn raw(&self) -> c::HANDLE {
68 self.0
69 }
c34b1796 70
85aaf69f 71 pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
9346a6ac 72 let mut read = 0;
32a655c1 73 let len = cmp::min(buf.len(), <c::DWORD>::max_value() as usize) as c::DWORD;
9346a6ac 74 let res = cvt(unsafe {
60c5eb7d 75 c::ReadFile(self.0, buf.as_mut_ptr() as c::LPVOID, len, &mut read, ptr::null_mut())
9346a6ac
AL
76 });
77
78 match res {
79 Ok(_) => Ok(read as usize),
80
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
84 // EOF on the pipe.
85 Err(ref e) if e.kind() == ErrorKind::BrokenPipe => Ok(0),
86
60c5eb7d 87 Err(e) => Err(e),
9346a6ac 88 }
85aaf69f
SL
89 }
90
48663c56
XL
91 pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
92 crate::io::default_read_vectored(|buf| self.read(buf), bufs)
93 }
94
c30ab7b3
SL
95 pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
96 let mut read = 0;
97 let len = cmp::min(buf.len(), <c::DWORD>::max_value() as usize) as c::DWORD;
98 let res = unsafe {
99 let mut overlapped: c::OVERLAPPED = mem::zeroed();
100 overlapped.Offset = offset as u32;
101 overlapped.OffsetHigh = (offset >> 32) as u32;
60c5eb7d 102 cvt(c::ReadFile(self.0, buf.as_mut_ptr() as c::LPVOID, len, &mut read, &mut overlapped))
c30ab7b3
SL
103 };
104 match res {
105 Ok(_) => Ok(read as usize),
106 Err(ref e) if e.raw_os_error() == Some(c::ERROR_HANDLE_EOF as i32) => Ok(0),
107 Err(e) => Err(e),
108 }
109 }
110
60c5eb7d
XL
111 pub unsafe fn read_overlapped(
112 &self,
113 buf: &mut [u8],
114 overlapped: *mut c::OVERLAPPED,
115 ) -> io::Result<Option<usize>> {
54a0048b
SL
116 let len = cmp::min(buf.len(), <c::DWORD>::max_value() as usize) as c::DWORD;
117 let mut amt = 0;
ba9703b0 118 let res = cvt(c::ReadFile(self.0, buf.as_ptr() as c::LPVOID, len, &mut amt, overlapped));
54a0048b
SL
119 match res {
120 Ok(_) => Ok(Some(amt as usize)),
121 Err(e) => {
122 if e.raw_os_error() == Some(c::ERROR_IO_PENDING as i32) {
123 Ok(None)
124 } else if e.raw_os_error() == Some(c::ERROR_BROKEN_PIPE as i32) {
125 Ok(Some(0))
126 } else {
127 Err(e)
128 }
129 }
130 }
131 }
132
60c5eb7d
XL
133 pub fn overlapped_result(
134 &self,
135 overlapped: *mut c::OVERLAPPED,
136 wait: bool,
137 ) -> io::Result<usize> {
54a0048b
SL
138 unsafe {
139 let mut bytes = 0;
60c5eb7d 140 let wait = if wait { c::TRUE } else { c::FALSE };
ba9703b0 141 let res = cvt(c::GetOverlappedResult(self.raw(), overlapped, &mut bytes, wait));
54a0048b
SL
142 match res {
143 Ok(_) => Ok(bytes as usize),
144 Err(e) => {
60c5eb7d
XL
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)
147 {
54a0048b
SL
148 Ok(0)
149 } else {
150 Err(e)
151 }
152 }
153 }
154 }
155 }
156
157 pub fn cancel_io(&self) -> io::Result<()> {
dfeec247 158 unsafe { cvt(c::CancelIo(self.raw())).map(drop) }
54a0048b
SL
159 }
160
85aaf69f 161 pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
9346a6ac 162 let mut amt = 0;
32a655c1 163 let len = cmp::min(buf.len(), <c::DWORD>::max_value() as usize) as c::DWORD;
54a0048b 164 cvt(unsafe {
60c5eb7d 165 c::WriteFile(self.0, buf.as_ptr() as c::LPVOID, len, &mut amt, ptr::null_mut())
54a0048b 166 })?;
9346a6ac 167 Ok(amt as usize)
85aaf69f 168 }
bd371182 169
48663c56
XL
170 pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
171 crate::io::default_write_vectored(|buf| self.write(buf), bufs)
172 }
173
c30ab7b3
SL
174 pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
175 let mut written = 0;
176 let len = cmp::min(buf.len(), <c::DWORD>::max_value() as usize) as c::DWORD;
177 unsafe {
178 let mut overlapped: c::OVERLAPPED = mem::zeroed();
179 overlapped.Offset = offset as u32;
180 overlapped.OffsetHigh = (offset >> 32) as u32;
60c5eb7d
XL
181 cvt(c::WriteFile(
182 self.0,
183 buf.as_ptr() as c::LPVOID,
184 len,
185 &mut written,
186 &mut overlapped,
187 ))?;
c30ab7b3
SL
188 }
189 Ok(written as usize)
190 }
191
60c5eb7d
XL
192 pub fn duplicate(
193 &self,
194 access: c::DWORD,
195 inherit: bool,
196 options: c::DWORD,
197 ) -> io::Result<Handle> {
92a42be0 198 let mut ret = 0 as c::HANDLE;
54a0048b 199 cvt(unsafe {
92a42be0 200 let cur_proc = c::GetCurrentProcess();
60c5eb7d
XL
201 c::DuplicateHandle(
202 cur_proc,
203 self.0,
204 cur_proc,
205 &mut ret,
206 access,
207 inherit as c::BOOL,
208 options,
209 )
54a0048b 210 })?;
bd371182
AL
211 Ok(Handle::new(ret))
212 }
85aaf69f 213}
54a0048b
SL
214
215impl<'a> Read for &'a RawHandle {
216 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
217 (**self).read(buf)
218 }
48663c56
XL
219
220 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
221 (**self).read_vectored(bufs)
222 }
54a0048b 223}