]> git.proxmox.com Git - rustc.git/blame - src/libstd/sys/windows/handle.rs
Imported Upstream version 1.2.0+dfsg1
[rustc.git] / src / libstd / sys / windows / handle.rs
CommitLineData
85aaf69f
SL
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
11use prelude::v1::*;
12
85aaf69f 13use io::ErrorKind;
c34b1796 14use io;
bd371182 15use libc::funcs::extra::kernel32::{GetCurrentProcess, DuplicateHandle};
c34b1796
AL
16use libc::{self, HANDLE};
17use mem;
62682a34 18use ops::Deref;
85aaf69f
SL
19use ptr;
20use sys::cvt;
21
62682a34
SL
22/// An owned container for `HANDLE` object, closing them on Drop.
23///
24/// All methods are inherited through a `Deref` impl to `RawHandle`
25pub struct Handle(RawHandle);
85aaf69f 26
62682a34
SL
27/// A wrapper type for `HANDLE` objects to give them proper Send/Sync inference
28/// as well as Rust-y methods.
29///
30/// This does **not** drop the handle when it goes out of scope, use `Handle`
31/// instead for that.
32#[derive(Copy, Clone)]
33pub struct RawHandle(HANDLE);
34
35unsafe impl Send for RawHandle {}
36unsafe impl Sync for RawHandle {}
85aaf69f
SL
37
38impl Handle {
39 pub fn new(handle: HANDLE) -> Handle {
62682a34 40 Handle(RawHandle::new(handle))
85aaf69f
SL
41 }
42
c34b1796 43 pub fn into_raw(self) -> HANDLE {
62682a34 44 let ret = self.raw();
bd371182 45 mem::forget(self);
c34b1796
AL
46 return ret;
47 }
62682a34
SL
48}
49
50impl Deref for Handle {
51 type Target = RawHandle;
52 fn deref(&self) -> &RawHandle { &self.0 }
53}
54
55impl Drop for Handle {
56 fn drop(&mut self) {
57 unsafe { let _ = libc::CloseHandle(self.raw()); }
58 }
59}
60
61impl RawHandle {
62 pub fn new(handle: HANDLE) -> RawHandle {
63 RawHandle(handle)
64 }
65
66 pub fn raw(&self) -> HANDLE { self.0 }
c34b1796 67
85aaf69f 68 pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
9346a6ac
AL
69 let mut read = 0;
70 let res = cvt(unsafe {
71 libc::ReadFile(self.0, buf.as_ptr() as libc::LPVOID,
72 buf.len() as libc::DWORD, &mut read,
73 ptr::null_mut())
74 });
75
76 match res {
77 Ok(_) => Ok(read as usize),
78
79 // The special treatment of BrokenPipe is to deal with Windows
80 // pipe semantics, which yields this error when *reading* from
81 // a pipe after the other end has closed; we interpret that as
82 // EOF on the pipe.
83 Err(ref e) if e.kind() == ErrorKind::BrokenPipe => Ok(0),
84
85 Err(e) => Err(e)
86 }
85aaf69f
SL
87 }
88
89 pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
9346a6ac
AL
90 let mut amt = 0;
91 try!(cvt(unsafe {
92 libc::WriteFile(self.0, buf.as_ptr() as libc::LPVOID,
93 buf.len() as libc::DWORD, &mut amt,
94 ptr::null_mut())
95 }));
96 Ok(amt as usize)
85aaf69f 97 }
bd371182
AL
98
99 pub fn duplicate(&self, access: libc::DWORD, inherit: bool,
100 options: libc::DWORD) -> io::Result<Handle> {
101 let mut ret = 0 as libc::HANDLE;
102 try!(cvt(unsafe {
103 let cur_proc = GetCurrentProcess();
104 DuplicateHandle(cur_proc, self.0, cur_proc, &mut ret,
105 access, inherit as libc::BOOL,
106 options)
107 }));
108 Ok(Handle::new(ret))
109 }
85aaf69f 110}