]> git.lizzy.rs Git - rust.git/blob - src/libstd/sys/unix/ext.rs
Auto merge of #22541 - Manishearth:rollup, r=Gankro
[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 #![unstable(feature = "std_misc")]
33
34 use prelude::v1::*;
35
36 use ffi::{CString, NulError, OsStr, OsString};
37 use fs::{self, Permissions, OpenOptions};
38 use net;
39 use mem;
40 use process;
41 use sys;
42 use sys::os_str::Buf;
43 use sys_common::{AsInner, AsInnerMut, IntoInner, FromInner};
44 use libc::{self, gid_t, uid_t};
45
46 use old_io;
47
48 /// Raw file descriptors.
49 pub type Fd = libc::c_int;
50
51 /// Extract raw file descriptor
52 pub trait AsRawFd {
53     /// Extract the raw file descriptor, without taking any ownership.
54     fn as_raw_fd(&self) -> Fd;
55 }
56
57 impl AsRawFd for old_io::fs::File {
58     fn as_raw_fd(&self) -> Fd {
59         self.as_inner().fd()
60     }
61 }
62
63 impl AsRawFd for fs::File {
64     fn as_raw_fd(&self) -> Fd {
65         self.as_inner().fd().raw()
66     }
67 }
68
69 impl AsRawFd for old_io::pipe::PipeStream {
70     fn as_raw_fd(&self) -> Fd {
71         self.as_inner().fd()
72     }
73 }
74
75 impl AsRawFd for old_io::net::pipe::UnixStream {
76     fn as_raw_fd(&self) -> Fd {
77         self.as_inner().fd()
78     }
79 }
80
81 impl AsRawFd for old_io::net::pipe::UnixListener {
82     fn as_raw_fd(&self) -> Fd {
83         self.as_inner().fd()
84     }
85 }
86
87 impl AsRawFd for old_io::net::pipe::UnixAcceptor {
88     fn as_raw_fd(&self) -> Fd {
89         self.as_inner().fd()
90     }
91 }
92
93 impl AsRawFd for old_io::net::tcp::TcpStream {
94     fn as_raw_fd(&self) -> Fd {
95         self.as_inner().fd()
96     }
97 }
98
99 impl AsRawFd for old_io::net::tcp::TcpListener {
100     fn as_raw_fd(&self) -> Fd {
101         self.as_inner().fd()
102     }
103 }
104
105 impl AsRawFd for old_io::net::tcp::TcpAcceptor {
106     fn as_raw_fd(&self) -> Fd {
107         self.as_inner().fd()
108     }
109 }
110
111 impl AsRawFd for old_io::net::udp::UdpSocket {
112     fn as_raw_fd(&self) -> Fd {
113         self.as_inner().fd()
114     }
115 }
116
117 impl AsRawFd for net::TcpStream {
118     fn as_raw_fd(&self) -> Fd { *self.as_inner().socket().as_inner() }
119 }
120 impl AsRawFd for net::TcpListener {
121     fn as_raw_fd(&self) -> Fd { *self.as_inner().socket().as_inner() }
122 }
123 impl AsRawFd for net::UdpSocket {
124     fn as_raw_fd(&self) -> Fd { *self.as_inner().socket().as_inner() }
125 }
126
127 ////////////////////////////////////////////////////////////////////////////////
128 // OsString and OsStr
129 ////////////////////////////////////////////////////////////////////////////////
130
131 /// Unix-specific extensions to `OsString`.
132 pub trait OsStringExt {
133     /// Create an `OsString` from a byte vector.
134     fn from_vec(vec: Vec<u8>) -> Self;
135
136     /// Yield the underlying byte vector of this `OsString`.
137     fn into_vec(self) -> Vec<u8>;
138 }
139
140 impl OsStringExt for OsString {
141     fn from_vec(vec: Vec<u8>) -> OsString {
142         FromInner::from_inner(Buf { inner: vec })
143     }
144
145     fn into_vec(self) -> Vec<u8> {
146         self.into_inner().inner
147     }
148 }
149
150 /// Unix-specific extensions to `OsStr`.
151 pub trait OsStrExt {
152     fn from_bytes(slice: &[u8]) -> &OsStr;
153
154     /// Get the underlying byte view of the `OsStr` slice.
155     fn as_bytes(&self) -> &[u8];
156
157     /// Convert the `OsStr` slice into a `CString`.
158     fn to_cstring(&self) -> Result<CString, NulError>;
159 }
160
161 impl OsStrExt for OsStr {
162     fn from_bytes(slice: &[u8]) -> &OsStr {
163         unsafe { mem::transmute(slice) }
164     }
165     fn as_bytes(&self) -> &[u8] {
166         &self.as_inner().inner
167     }
168
169     fn to_cstring(&self) -> Result<CString, NulError> {
170         CString::new(self.as_bytes())
171     }
172 }
173
174 // Unix-specific extensions to `Permissions`
175 pub trait PermissionsExt {
176     fn set_mode(&mut self, mode: i32);
177 }
178
179 impl PermissionsExt for Permissions {
180     fn set_mode(&mut self, mode: i32) {
181         *self = FromInner::from_inner(FromInner::from_inner(mode));
182     }
183 }
184
185 // Unix-specific extensions to `OpenOptions`
186 pub trait OpenOptionsExt {
187     /// Set the mode bits that a new file will be created with.
188     ///
189     /// If a new file is created as part of a `File::open_opts` call then this
190     /// specified `mode` will be used as the permission bits for the new file.
191     fn mode(&mut self, mode: i32) -> &mut Self;
192 }
193
194 impl OpenOptionsExt for OpenOptions {
195     fn mode(&mut self, mode: i32) -> &mut OpenOptions {
196         self.as_inner_mut().mode(mode); self
197     }
198 }
199
200 ////////////////////////////////////////////////////////////////////////////////
201 // Process and Command
202 ////////////////////////////////////////////////////////////////////////////////
203
204 /// Unix-specific extensions to the `std::process::Command` builder
205 pub trait CommandExt {
206     /// Sets the child process's user id. This translates to a
207     /// `setuid` call in the child process. Failure in the `setuid`
208     /// call will cause the spawn to fail.
209     fn uid(&mut self, id: uid_t) -> &mut process::Command;
210
211     /// Similar to `uid`, but sets the group id of the child process. This has
212     /// the same semantics as the `uid` field.
213     fn gid(&mut self, id: gid_t) -> &mut process::Command;
214 }
215
216 impl CommandExt for process::Command {
217     fn uid(&mut self, id: uid_t) -> &mut process::Command {
218         self.as_inner_mut().uid = Some(id);
219         self
220     }
221
222     fn gid(&mut self, id: gid_t) -> &mut process::Command {
223         self.as_inner_mut().gid = Some(id);
224         self
225     }
226 }
227
228 /// Unix-specific extensions to `std::process::ExitStatus`
229 pub trait ExitStatusExt {
230     /// If the process was terminated by a signal, returns that signal.
231     fn signal(&self) -> Option<i32>;
232 }
233
234 impl ExitStatusExt for process::ExitStatus {
235     fn signal(&self) -> Option<i32> {
236         match *self.as_inner() {
237             sys::process2::ExitStatus::Signal(s) => Some(s),
238             _ => None
239         }
240     }
241 }
242
243 ////////////////////////////////////////////////////////////////////////////////
244 // Prelude
245 ////////////////////////////////////////////////////////////////////////////////
246
247 /// A prelude for conveniently writing platform-specific code.
248 ///
249 /// Includes all extension traits, and some important type definitions.
250 pub mod prelude {
251     #[doc(no_inline)]
252     pub use super::{Fd, AsRawFd, OsStrExt, OsStringExt, PermissionsExt};
253     #[doc(no_inline)]
254     pub use super::{CommandExt, ExitStatusExt};
255 }