]> git.proxmox.com Git - rustc.git/blob - src/libstd/sys/windows/handle.rs
Imported Upstream version 1.6.0+dfsg1
[rustc.git] / src / libstd / sys / windows / handle.rs
1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use io::ErrorKind;
12 use io;
13 use mem;
14 use ops::Deref;
15 use ptr;
16 use sys::c;
17 use sys::cvt;
18
19 /// An owned container for `HANDLE` object, closing them on Drop.
20 ///
21 /// All methods are inherited through a `Deref` impl to `RawHandle`
22 pub struct Handle(RawHandle);
23
24 /// A wrapper type for `HANDLE` objects to give them proper Send/Sync inference
25 /// as well as Rust-y methods.
26 ///
27 /// This does **not** drop the handle when it goes out of scope, use `Handle`
28 /// instead for that.
29 #[derive(Copy, Clone)]
30 pub struct RawHandle(c::HANDLE);
31
32 unsafe impl Send for RawHandle {}
33 unsafe impl Sync for RawHandle {}
34
35 impl Handle {
36 pub fn new(handle: c::HANDLE) -> Handle {
37 Handle(RawHandle::new(handle))
38 }
39
40 pub fn into_raw(self) -> c::HANDLE {
41 let ret = self.raw();
42 mem::forget(self);
43 return ret;
44 }
45 }
46
47 impl Deref for Handle {
48 type Target = RawHandle;
49 fn deref(&self) -> &RawHandle { &self.0 }
50 }
51
52 impl Drop for Handle {
53 fn drop(&mut self) {
54 unsafe { let _ = c::CloseHandle(self.raw()); }
55 }
56 }
57
58 impl RawHandle {
59 pub fn new(handle: c::HANDLE) -> RawHandle {
60 RawHandle(handle)
61 }
62
63 pub fn raw(&self) -> c::HANDLE { self.0 }
64
65 pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
66 let mut read = 0;
67 let res = cvt(unsafe {
68 c::ReadFile(self.0, buf.as_ptr() as c::LPVOID,
69 buf.len() as c::DWORD, &mut read,
70 ptr::null_mut())
71 });
72
73 match res {
74 Ok(_) => Ok(read as usize),
75
76 // The special treatment of BrokenPipe is to deal with Windows
77 // pipe semantics, which yields this error when *reading* from
78 // a pipe after the other end has closed; we interpret that as
79 // EOF on the pipe.
80 Err(ref e) if e.kind() == ErrorKind::BrokenPipe => Ok(0),
81
82 Err(e) => Err(e)
83 }
84 }
85
86 pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
87 let mut amt = 0;
88 try!(cvt(unsafe {
89 c::WriteFile(self.0, buf.as_ptr() as c::LPVOID,
90 buf.len() as c::DWORD, &mut amt,
91 ptr::null_mut())
92 }));
93 Ok(amt as usize)
94 }
95
96 pub fn duplicate(&self, access: c::DWORD, inherit: bool,
97 options: c::DWORD) -> io::Result<Handle> {
98 let mut ret = 0 as c::HANDLE;
99 try!(cvt(unsafe {
100 let cur_proc = c::GetCurrentProcess();
101 c::DuplicateHandle(cur_proc, self.0, cur_proc, &mut ret,
102 access, inherit as c::BOOL,
103 options)
104 }));
105 Ok(Handle::new(ret))
106 }
107 }