]> git.proxmox.com Git - rustc.git/blame - src/libstd/sys/windows/handle.rs
New upstream version 1.41.1+dfsg1
[rustc.git] / src / libstd / sys / windows / handle.rs
CommitLineData
54a0048b
SL
1#![unstable(issue = "0", feature = "windows_handle")]
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;
60c5eb7d
XL
118 let res =
119 cvt({ c::ReadFile(self.0, buf.as_ptr() as c::LPVOID, len, &mut amt, overlapped) });
54a0048b
SL
120 match res {
121 Ok(_) => Ok(Some(amt as usize)),
122 Err(e) => {
123 if e.raw_os_error() == Some(c::ERROR_IO_PENDING as i32) {
124 Ok(None)
125 } else if e.raw_os_error() == Some(c::ERROR_BROKEN_PIPE as i32) {
126 Ok(Some(0))
127 } else {
128 Err(e)
129 }
130 }
131 }
132 }
133
60c5eb7d
XL
134 pub fn overlapped_result(
135 &self,
136 overlapped: *mut c::OVERLAPPED,
137 wait: bool,
138 ) -> io::Result<usize> {
54a0048b
SL
139 unsafe {
140 let mut bytes = 0;
60c5eb7d
XL
141 let wait = if wait { c::TRUE } else { c::FALSE };
142 let res = cvt({ c::GetOverlappedResult(self.raw(), overlapped, &mut bytes, wait) });
54a0048b
SL
143 match res {
144 Ok(_) => Ok(bytes as usize),
145 Err(e) => {
60c5eb7d
XL
146 if e.raw_os_error() == Some(c::ERROR_HANDLE_EOF as i32)
147 || e.raw_os_error() == Some(c::ERROR_BROKEN_PIPE as i32)
148 {
54a0048b
SL
149 Ok(0)
150 } else {
151 Err(e)
152 }
153 }
154 }
155 }
156 }
157
158 pub fn cancel_io(&self) -> io::Result<()> {
60c5eb7d 159 unsafe { cvt(c::CancelIo(self.raw())).map(|_| ()) }
54a0048b
SL
160 }
161
85aaf69f 162 pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
9346a6ac 163 let mut amt = 0;
32a655c1 164 let len = cmp::min(buf.len(), <c::DWORD>::max_value() as usize) as c::DWORD;
54a0048b 165 cvt(unsafe {
60c5eb7d 166 c::WriteFile(self.0, buf.as_ptr() as c::LPVOID, len, &mut amt, ptr::null_mut())
54a0048b 167 })?;
9346a6ac 168 Ok(amt as usize)
85aaf69f 169 }
bd371182 170
48663c56
XL
171 pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
172 crate::io::default_write_vectored(|buf| self.write(buf), bufs)
173 }
174
c30ab7b3
SL
175 pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
176 let mut written = 0;
177 let len = cmp::min(buf.len(), <c::DWORD>::max_value() as usize) as c::DWORD;
178 unsafe {
179 let mut overlapped: c::OVERLAPPED = mem::zeroed();
180 overlapped.Offset = offset as u32;
181 overlapped.OffsetHigh = (offset >> 32) as u32;
60c5eb7d
XL
182 cvt(c::WriteFile(
183 self.0,
184 buf.as_ptr() as c::LPVOID,
185 len,
186 &mut written,
187 &mut overlapped,
188 ))?;
c30ab7b3
SL
189 }
190 Ok(written as usize)
191 }
192
60c5eb7d
XL
193 pub fn duplicate(
194 &self,
195 access: c::DWORD,
196 inherit: bool,
197 options: c::DWORD,
198 ) -> io::Result<Handle> {
92a42be0 199 let mut ret = 0 as c::HANDLE;
54a0048b 200 cvt(unsafe {
92a42be0 201 let cur_proc = c::GetCurrentProcess();
60c5eb7d
XL
202 c::DuplicateHandle(
203 cur_proc,
204 self.0,
205 cur_proc,
206 &mut ret,
207 access,
208 inherit as c::BOOL,
209 options,
210 )
54a0048b 211 })?;
bd371182
AL
212 Ok(Handle::new(ret))
213 }
85aaf69f 214}
54a0048b
SL
215
216impl<'a> Read for &'a RawHandle {
217 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
218 (**self).read(buf)
219 }
48663c56
XL
220
221 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
222 (**self).read_vectored(bufs)
223 }
54a0048b 224}