]> git.lizzy.rs Git - rust.git/blob - src/libstd/sys/unix/ext.rs
Auto merge of #23934 - lfairy:write-no-deref, r=alexcrichton
[rust.git] / src / libstd / sys / unix / 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 Unix platforms.
12 //!
13 //! For now, this module is limited to extracting file descriptors,
14 //! but its functionality will grow over time.
15 //!
16 //! # Example
17 //!
18 //! ```rust,ignore
19 //! #![feature(globs)]
20 //!
21 //! use std::old_io::fs::File;
22 //! use std::os::unix::prelude::*;
23 //!
24 //! fn main() {
25 //!     let f = File::create(&Path::new("foo.txt")).unwrap();
26 //!     let fd = f.as_raw_fd();
27 //!
28 //!     // use fd with native unix bindings
29 //! }
30 //! ```
31
32 #![stable(feature = "rust1", since = "1.0.0")]
33
34 /// Unix-specific extensions to general I/O primitives
35 #[stable(feature = "rust1", since = "1.0.0")]
36 pub mod io {
37     #[allow(deprecated)] use old_io;
38     use fs;
39     use libc;
40     use net;
41     use sys_common::{net2, AsInner, FromInner};
42     use sys;
43
44     /// Raw file descriptors.
45     #[stable(feature = "rust1", since = "1.0.0")]
46     pub type RawFd = libc::c_int;
47
48     /// A trait to extract the raw unix file descriptor from an underlying
49     /// object.
50     ///
51     /// This is only available on unix platforms and must be imported in order
52     /// to call the method. Windows platforms have a corresponding `AsRawHandle`
53     /// and `AsRawSocket` set of traits.
54     #[stable(feature = "rust1", since = "1.0.0")]
55     pub trait AsRawFd {
56         /// Extract the raw file descriptor.
57         ///
58         /// This method does **not** pass ownership of the raw file descriptor
59         /// to the caller. The descriptor is only guarantee to be valid while
60         /// the original object has not yet been destroyed.
61         #[stable(feature = "rust1", since = "1.0.0")]
62         fn as_raw_fd(&self) -> RawFd;
63     }
64
65     /// A trait to express the ability to construct an object from a raw file
66     /// descriptor.
67     #[unstable(feature = "from_raw_os",
68                reason = "recent addition to std::os::unix::io")]
69     pub trait FromRawFd {
70         /// Constructs a new instances of `Self` from the given raw file
71         /// descriptor.
72         ///
73         /// This function **consumes ownership** of the specified file
74         /// descriptor. The returned object will take responsibility for closing
75         /// it when the object goes out of scope.
76         ///
77         /// Callers should normally only pass in a valid file descriptor to this
78         /// method or otherwise methods will return errors.
79         fn from_raw_fd(fd: RawFd) -> Self;
80     }
81
82     #[allow(deprecated)]
83     #[stable(feature = "rust1", since = "1.0.0")]
84     impl AsRawFd for old_io::fs::File {
85         fn as_raw_fd(&self) -> RawFd {
86             self.as_inner().fd()
87         }
88     }
89
90     #[stable(feature = "rust1", since = "1.0.0")]
91     impl AsRawFd for fs::File {
92         fn as_raw_fd(&self) -> RawFd {
93             self.as_inner().fd().raw()
94         }
95     }
96     #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
97     impl FromRawFd for fs::File {
98         fn from_raw_fd(fd: RawFd) -> fs::File {
99             fs::File::from_inner(sys::fs2::File::from_inner(fd))
100         }
101     }
102
103     #[allow(deprecated)]
104     #[stable(feature = "rust1", since = "1.0.0")]
105     impl AsRawFd for old_io::pipe::PipeStream {
106         fn as_raw_fd(&self) -> RawFd {
107             self.as_inner().fd()
108         }
109     }
110
111     #[allow(deprecated)]
112     #[stable(feature = "rust1", since = "1.0.0")]
113     impl AsRawFd for old_io::net::pipe::UnixStream {
114         fn as_raw_fd(&self) -> RawFd {
115             self.as_inner().fd()
116         }
117     }
118
119     #[allow(deprecated)]
120     #[stable(feature = "rust1", since = "1.0.0")]
121     impl AsRawFd for old_io::net::pipe::UnixListener {
122         fn as_raw_fd(&self) -> RawFd {
123             self.as_inner().fd()
124         }
125     }
126
127     #[allow(deprecated)]
128     #[stable(feature = "rust1", since = "1.0.0")]
129     impl AsRawFd for old_io::net::pipe::UnixAcceptor {
130         fn as_raw_fd(&self) -> RawFd {
131             self.as_inner().fd()
132         }
133     }
134
135     #[stable(feature = "rust1", since = "1.0.0")]
136     #[allow(deprecated)]
137     impl AsRawFd for old_io::net::tcp::TcpStream {
138         fn as_raw_fd(&self) -> RawFd {
139             self.as_inner().fd()
140         }
141     }
142
143     #[stable(feature = "rust1", since = "1.0.0")]
144     #[allow(deprecated)]
145     impl AsRawFd for old_io::net::tcp::TcpListener {
146         fn as_raw_fd(&self) -> RawFd {
147             self.as_inner().fd()
148         }
149     }
150
151     #[stable(feature = "rust1", since = "1.0.0")]
152     #[allow(deprecated)]
153     impl AsRawFd for old_io::net::tcp::TcpAcceptor {
154         fn as_raw_fd(&self) -> RawFd {
155             self.as_inner().fd()
156         }
157     }
158
159     #[allow(deprecated)]
160     #[stable(feature = "rust1", since = "1.0.0")]
161     impl AsRawFd for old_io::net::udp::UdpSocket {
162         fn as_raw_fd(&self) -> RawFd {
163             self.as_inner().fd()
164         }
165     }
166
167     #[stable(feature = "rust1", since = "1.0.0")]
168     impl AsRawFd for net::TcpStream {
169         fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
170     }
171     #[stable(feature = "rust1", since = "1.0.0")]
172     impl AsRawFd for net::TcpListener {
173         fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
174     }
175     #[stable(feature = "rust1", since = "1.0.0")]
176     impl AsRawFd for net::UdpSocket {
177         fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
178     }
179
180     #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
181     impl FromRawFd for net::TcpStream {
182         fn from_raw_fd(fd: RawFd) -> net::TcpStream {
183             let socket = sys::net::Socket::from_inner(fd);
184             net::TcpStream::from_inner(net2::TcpStream::from_inner(socket))
185         }
186     }
187     #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
188     impl FromRawFd for net::TcpListener {
189         fn from_raw_fd(fd: RawFd) -> net::TcpListener {
190             let socket = sys::net::Socket::from_inner(fd);
191             net::TcpListener::from_inner(net2::TcpListener::from_inner(socket))
192         }
193     }
194     #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
195     impl FromRawFd for net::UdpSocket {
196         fn from_raw_fd(fd: RawFd) -> net::UdpSocket {
197             let socket = sys::net::Socket::from_inner(fd);
198             net::UdpSocket::from_inner(net2::UdpSocket::from_inner(socket))
199         }
200     }
201 }
202
203 ////////////////////////////////////////////////////////////////////////////////
204 // OsString and OsStr
205 ////////////////////////////////////////////////////////////////////////////////
206
207 /// Unix-specific extension to the primitives in the `std::ffi` module
208 #[stable(feature = "rust1", since = "1.0.0")]
209 pub mod ffi {
210     use ffi::{OsStr, OsString};
211     use mem;
212     use prelude::v1::*;
213     use sys::os_str::Buf;
214     use sys_common::{FromInner, IntoInner, AsInner};
215
216     /// Unix-specific extensions to `OsString`.
217     #[stable(feature = "rust1", since = "1.0.0")]
218     pub trait OsStringExt {
219         /// Create an `OsString` from a byte vector.
220         #[stable(feature = "rust1", since = "1.0.0")]
221         fn from_vec(vec: Vec<u8>) -> Self;
222
223         /// Yield the underlying byte vector of this `OsString`.
224         #[stable(feature = "rust1", since = "1.0.0")]
225         fn into_vec(self) -> Vec<u8>;
226     }
227
228     #[stable(feature = "rust1", since = "1.0.0")]
229     impl OsStringExt for OsString {
230         fn from_vec(vec: Vec<u8>) -> OsString {
231             FromInner::from_inner(Buf { inner: vec })
232         }
233         fn into_vec(self) -> Vec<u8> {
234             self.into_inner().inner
235         }
236     }
237
238     /// Unix-specific extensions to `OsStr`.
239     #[stable(feature = "rust1", since = "1.0.0")]
240     pub trait OsStrExt {
241         #[stable(feature = "rust1", since = "1.0.0")]
242         fn from_bytes(slice: &[u8]) -> &Self;
243
244         /// Get the underlying byte view of the `OsStr` slice.
245         #[stable(feature = "rust1", since = "1.0.0")]
246         fn as_bytes(&self) -> &[u8];
247     }
248
249     #[stable(feature = "rust1", since = "1.0.0")]
250     impl OsStrExt for OsStr {
251         fn from_bytes(slice: &[u8]) -> &OsStr {
252             unsafe { mem::transmute(slice) }
253         }
254         fn as_bytes(&self) -> &[u8] {
255             &self.as_inner().inner
256         }
257     }
258 }
259
260 /// Unix-specific extensions to primitives in the `std::fs` module.
261 #[unstable(feature = "fs_ext",
262            reason = "may want a more useful mode abstraction")]
263 pub mod fs {
264     use sys_common::{FromInner, AsInner, AsInnerMut};
265     use fs::{Permissions, OpenOptions};
266
267     /// Unix-specific extensions to `Permissions`
268     pub trait PermissionsExt {
269         fn mode(&self) -> i32;
270         fn set_mode(&mut self, mode: i32);
271     }
272
273     impl PermissionsExt for Permissions {
274         fn mode(&self) -> i32 { self.as_inner().mode() }
275
276         fn set_mode(&mut self, mode: i32) {
277             *self = FromInner::from_inner(FromInner::from_inner(mode));
278         }
279     }
280
281     /// Unix-specific extensions to `OpenOptions`
282     pub trait OpenOptionsExt {
283         /// Set the mode bits that a new file will be created with.
284         ///
285         /// If a new file is created as part of a `File::open_opts` call then this
286         /// specified `mode` will be used as the permission bits for the new file.
287         fn mode(&mut self, mode: i32) -> &mut Self;
288     }
289
290     impl OpenOptionsExt for OpenOptions {
291         fn mode(&mut self, mode: i32) -> &mut OpenOptions {
292             self.as_inner_mut().mode(mode); self
293         }
294     }
295 }
296
297 ////////////////////////////////////////////////////////////////////////////////
298 // Process and Command
299 ////////////////////////////////////////////////////////////////////////////////
300
301 /// Unix-specific extensions to primitives in the `std::process` module.
302 #[stable(feature = "rust1", since = "1.0.0")]
303 pub mod process {
304     use prelude::v1::*;
305     use libc::{uid_t, gid_t};
306     use process;
307     use sys;
308     use sys_common::{AsInnerMut, AsInner};
309
310     /// Unix-specific extensions to the `std::process::Command` builder
311     #[stable(feature = "rust1", since = "1.0.0")]
312     pub trait CommandExt {
313         /// Sets the child process's user id. This translates to a
314         /// `setuid` call in the child process. Failure in the `setuid`
315         /// call will cause the spawn to fail.
316         #[stable(feature = "rust1", since = "1.0.0")]
317         fn uid(&mut self, id: uid_t) -> &mut process::Command;
318
319         /// Similar to `uid`, but sets the group id of the child process. This has
320         /// the same semantics as the `uid` field.
321         #[stable(feature = "rust1", since = "1.0.0")]
322         fn gid(&mut self, id: gid_t) -> &mut process::Command;
323     }
324
325     #[stable(feature = "rust1", since = "1.0.0")]
326     impl CommandExt for process::Command {
327         fn uid(&mut self, id: uid_t) -> &mut process::Command {
328             self.as_inner_mut().uid = Some(id);
329             self
330         }
331
332         fn gid(&mut self, id: gid_t) -> &mut process::Command {
333             self.as_inner_mut().gid = Some(id);
334             self
335         }
336     }
337
338     /// Unix-specific extensions to `std::process::ExitStatus`
339     #[stable(feature = "rust1", since = "1.0.0")]
340     pub trait ExitStatusExt {
341         /// If the process was terminated by a signal, returns that signal.
342         #[stable(feature = "rust1", since = "1.0.0")]
343         fn signal(&self) -> Option<i32>;
344     }
345
346     #[stable(feature = "rust1", since = "1.0.0")]
347     impl ExitStatusExt for process::ExitStatus {
348         fn signal(&self) -> Option<i32> {
349             match *self.as_inner() {
350                 sys::process2::ExitStatus::Signal(s) => Some(s),
351                 _ => None
352             }
353         }
354     }
355 }
356
357 ////////////////////////////////////////////////////////////////////////////////
358 // Prelude
359 ////////////////////////////////////////////////////////////////////////////////
360
361 /// A prelude for conveniently writing platform-specific code.
362 ///
363 /// Includes all extension traits, and some important type definitions.
364 #[stable(feature = "rust1", since = "1.0.0")]
365 pub mod prelude {
366     #[doc(no_inline)]
367     pub use super::io::{RawFd, AsRawFd};
368     #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
369     pub use super::ffi::{OsStrExt, OsStringExt};
370     #[doc(no_inline)]
371     pub use super::fs::{PermissionsExt, OpenOptionsExt};
372     #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
373     pub use super::process::{CommandExt, ExitStatusExt};
374 }