]> git.lizzy.rs Git - rust.git/blob - src/libstd/sys/windows/ext.rs
Auto merge of #24865 - bluss:range-size, r=alexcrichton
[rust.git] / src / libstd / sys / windows / ext.rs
1 // Copyright 2014 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 //! Experimental extensions to `std` for Windows.
12 //!
13 //! For now, this module is limited to extracting handles, file
14 //! descriptors, and sockets, but its functionality will grow over
15 //! time.
16
17 #![stable(feature = "rust1", since = "1.0.0")]
18
19 #[stable(feature = "rust1", since = "1.0.0")]
20 pub mod io {
21     use fs;
22     use libc;
23     use net;
24     use sys_common::{net2, AsInner, FromInner};
25     use sys;
26
27     /// Raw HANDLEs.
28     #[stable(feature = "rust1", since = "1.0.0")]
29     pub type RawHandle = libc::HANDLE;
30
31     /// Raw SOCKETs.
32     #[stable(feature = "rust1", since = "1.0.0")]
33     pub type RawSocket = libc::SOCKET;
34
35     /// Extract raw handles.
36     #[stable(feature = "rust1", since = "1.0.0")]
37     pub trait AsRawHandle {
38         /// Extracts the raw handle, without taking any ownership.
39         #[stable(feature = "rust1", since = "1.0.0")]
40         fn as_raw_handle(&self) -> RawHandle;
41     }
42
43     /// Construct I/O objects from raw handles.
44     #[unstable(feature = "from_raw_os",
45                reason = "recent addition to the std::os::windows::io module")]
46     pub trait FromRawHandle {
47         /// Constructs a new I/O object from the specified raw handle.
48         ///
49         /// This function will **consume ownership** of the handle given,
50         /// passing responsibility for closing the handle to the returned
51         /// object.
52         ///
53         /// This function is also unsafe as the primitives currently returned
54         /// have the contract that they are the sole owner of the file
55         /// descriptor they are wrapping. Usage of this function could
56         /// accidentally allow violating this contract which can cause memory
57         /// unsafety in code that relies on it being true.
58         unsafe fn from_raw_handle(handle: RawHandle) -> Self;
59     }
60
61     #[stable(feature = "rust1", since = "1.0.0")]
62     impl AsRawHandle for fs::File {
63         fn as_raw_handle(&self) -> RawHandle {
64             self.as_inner().handle().raw()
65         }
66     }
67
68     #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
69     impl FromRawHandle for fs::File {
70         unsafe fn from_raw_handle(handle: RawHandle) -> fs::File {
71             fs::File::from_inner(sys::fs2::File::from_inner(handle))
72         }
73     }
74
75     /// Extract raw sockets.
76     #[stable(feature = "rust1", since = "1.0.0")]
77     pub trait AsRawSocket {
78         /// Extracts the underlying raw socket from this object.
79         #[stable(feature = "rust1", since = "1.0.0")]
80         fn as_raw_socket(&self) -> RawSocket;
81     }
82
83     /// Create I/O objects from raw sockets.
84     #[unstable(feature = "from_raw_os", reason = "recent addition to module")]
85     pub trait FromRawSocket {
86         /// Creates a new I/O object from the given raw socket.
87         ///
88         /// This function will **consume ownership** of the socket provided and
89         /// it will be closed when the returned object goes out of scope.
90         ///
91         /// This function is also unsafe as the primitives currently returned
92         /// have the contract that they are the sole owner of the file
93         /// descriptor they are wrapping. Usage of this function could
94         /// accidentally allow violating this contract which can cause memory
95         /// unsafety in code that relies on it being true.
96         unsafe fn from_raw_socket(sock: RawSocket) -> Self;
97     }
98
99     #[stable(feature = "rust1", since = "1.0.0")]
100     impl AsRawSocket for net::TcpStream {
101         fn as_raw_socket(&self) -> RawSocket {
102             *self.as_inner().socket().as_inner()
103         }
104     }
105     #[stable(feature = "rust1", since = "1.0.0")]
106     impl AsRawSocket for net::TcpListener {
107         fn as_raw_socket(&self) -> RawSocket {
108             *self.as_inner().socket().as_inner()
109         }
110     }
111     #[stable(feature = "rust1", since = "1.0.0")]
112     impl AsRawSocket for net::UdpSocket {
113         fn as_raw_socket(&self) -> RawSocket {
114             *self.as_inner().socket().as_inner()
115         }
116     }
117
118     #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
119     impl FromRawSocket for net::TcpStream {
120         unsafe fn from_raw_socket(sock: RawSocket) -> net::TcpStream {
121             let sock = sys::net::Socket::from_inner(sock);
122             net::TcpStream::from_inner(net2::TcpStream::from_inner(sock))
123         }
124     }
125     #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
126     impl FromRawSocket for net::TcpListener {
127         unsafe fn from_raw_socket(sock: RawSocket) -> net::TcpListener {
128             let sock = sys::net::Socket::from_inner(sock);
129             net::TcpListener::from_inner(net2::TcpListener::from_inner(sock))
130         }
131     }
132     #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
133     impl FromRawSocket for net::UdpSocket {
134         unsafe fn from_raw_socket(sock: RawSocket) -> net::UdpSocket {
135             let sock = sys::net::Socket::from_inner(sock);
136             net::UdpSocket::from_inner(net2::UdpSocket::from_inner(sock))
137         }
138     }
139 }
140
141 /// Windows-specific extensions to the primitives in the `std::ffi` module.
142 #[stable(feature = "rust1", since = "1.0.0")]
143 pub mod ffi {
144     use ffi::{OsString, OsStr};
145     use sys::os_str::Buf;
146     use sys_common::wtf8::Wtf8Buf;
147     use sys_common::{FromInner, AsInner};
148
149     pub use sys_common::wtf8::EncodeWide;
150
151     /// Windows-specific extensions to `OsString`.
152     #[stable(feature = "rust1", since = "1.0.0")]
153     pub trait OsStringExt {
154         /// Creates an `OsString` from a potentially ill-formed UTF-16 slice of
155         /// 16-bit code units.
156         ///
157         /// This is lossless: calling `.encode_wide()` on the resulting string
158         /// will always return the original code units.
159         #[stable(feature = "rust1", since = "1.0.0")]
160         fn from_wide(wide: &[u16]) -> Self;
161     }
162
163     #[stable(feature = "rust1", since = "1.0.0")]
164     impl OsStringExt for OsString {
165         fn from_wide(wide: &[u16]) -> OsString {
166             FromInner::from_inner(Buf { inner: Wtf8Buf::from_wide(wide) })
167         }
168     }
169
170     /// Windows-specific extensions to `OsStr`.
171     #[stable(feature = "rust1", since = "1.0.0")]
172     pub trait OsStrExt {
173         /// Re-encodes an `OsStr` as a wide character sequence,
174         /// i.e. potentially ill-formed UTF-16.
175         ///
176         /// This is lossless. Note that the encoding does not include a final
177         /// null.
178         #[stable(feature = "rust1", since = "1.0.0")]
179         fn encode_wide(&self) -> EncodeWide;
180     }
181
182     #[stable(feature = "rust1", since = "1.0.0")]
183     impl OsStrExt for OsStr {
184         fn encode_wide(&self) -> EncodeWide {
185             self.as_inner().inner.encode_wide()
186         }
187     }
188 }
189
190 /// Windows-specific extensions for the primitives in `std::fs`
191 #[unstable(feature = "fs_ext", reason = "may require more thought/methods")]
192 pub mod fs {
193     use fs::OpenOptions;
194     use sys;
195     use sys_common::AsInnerMut;
196     use path::Path;
197     use convert::AsRef;
198     use io;
199
200     /// Windows-specific extensions to `OpenOptions`
201     pub trait OpenOptionsExt {
202         /// Overrides the `dwDesiredAccess` argument to the call to `CreateFile`
203         /// with the specified value.
204         fn desired_access(&mut self, access: i32) -> &mut Self;
205
206         /// Overrides the `dwCreationDisposition` argument to the call to
207         /// `CreateFile` with the specified value.
208         ///
209         /// This will override any values of the standard `create` flags, for
210         /// example.
211         fn creation_disposition(&mut self, val: i32) -> &mut Self;
212
213         /// Overrides the `dwFlagsAndAttributes` argument to the call to
214         /// `CreateFile` with the specified value.
215         ///
216         /// This will override any values of the standard flags on the
217         /// `OpenOptions` structure.
218         fn flags_and_attributes(&mut self, val: i32) -> &mut Self;
219
220         /// Overrides the `dwShareMode` argument to the call to `CreateFile` with
221         /// the specified value.
222         ///
223         /// This will override any values of the standard flags on the
224         /// `OpenOptions` structure.
225         fn share_mode(&mut self, val: i32) -> &mut Self;
226     }
227
228     impl OpenOptionsExt for OpenOptions {
229         fn desired_access(&mut self, access: i32) -> &mut OpenOptions {
230             self.as_inner_mut().desired_access(access); self
231         }
232         fn creation_disposition(&mut self, access: i32) -> &mut OpenOptions {
233             self.as_inner_mut().creation_disposition(access); self
234         }
235         fn flags_and_attributes(&mut self, access: i32) -> &mut OpenOptions {
236             self.as_inner_mut().flags_and_attributes(access); self
237         }
238         fn share_mode(&mut self, access: i32) -> &mut OpenOptions {
239             self.as_inner_mut().share_mode(access); self
240         }
241     }
242
243     /// Creates a new file symbolic link on the filesystem.
244     ///
245     /// The `dst` path will be a file symbolic link pointing to the `src`
246     /// path.
247     ///
248     /// # Examples
249     ///
250     /// ```ignore
251     /// #![feature(fs_ext)]
252     /// use std::os::windows::fs;
253     ///
254     /// # fn foo() -> std::io::Result<()> {
255     /// try!(fs::symlink_file("a.txt", "b.txt"));
256     /// # Ok(())
257     /// # }
258     /// ```
259     #[stable(feature = "rust1", since = "1.0.0")]
260     pub fn symlink_file<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q)
261                                                         -> io::Result<()>
262     {
263         sys::fs2::symlink_inner(src.as_ref(), dst.as_ref(), false)
264     }
265
266     /// Creates a new directory symlink on the filesystem.
267     ///
268     /// The `dst` path will be a directory symbolic link pointing to the `src`
269     /// path.
270     ///
271     /// # Examples
272     ///
273     /// ```ignore
274     /// #![feature(fs_ext)]
275     /// use std::os::windows::fs;
276     ///
277     /// # fn foo() -> std::io::Result<()> {
278     /// try!(fs::symlink_file("a", "b"));
279     /// # Ok(())
280     /// # }
281     /// ```
282     #[stable(feature = "rust1", since = "1.0.0")]
283     pub fn symlink_dir<P: AsRef<Path>, Q: AsRef<Path>> (src: P, dst: Q)
284                                                         -> io::Result<()>
285     {
286         sys::fs2::symlink_inner(src.as_ref(), dst.as_ref(), true)
287     }
288 }
289
290 /// A prelude for conveniently writing platform-specific code.
291 ///
292 /// Includes all extension traits, and some important type definitions.
293 #[stable(feature = "rust1", since = "1.0.0")]
294 pub mod prelude {
295     #[doc(no_inline)]
296     pub use super::io::{RawSocket, RawHandle, AsRawSocket, AsRawHandle};
297     #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
298     pub use super::ffi::{OsStrExt, OsStringExt};
299     #[doc(no_inline)]
300     pub use super::fs::OpenOptionsExt;
301 }