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.
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.
11 //! Experimental extensions to `std` for Unix platforms.
13 //! For now, this module is limited to extracting file descriptors,
14 //! but its functionality will grow over time.
19 //! #![feature(globs)]
21 //! use std::old_io::fs::File;
22 //! use std::os::unix::prelude::*;
25 //! let f = File::create(&Path::new("foo.txt")).unwrap();
26 //! let fd = f.as_raw_fd();
28 //! // use fd with native unix bindings
32 #![unstable(feature = "std_misc")]
36 use ffi::{CString, NulError, OsStr, OsString};
37 use fs::{self, Permissions, OpenOptions};
43 use sys_common::{AsInner, AsInnerMut, IntoInner, FromInner};
44 use libc::{self, gid_t, uid_t};
48 /// Raw file descriptors.
49 pub type Fd = libc::c_int;
51 /// Extract raw file descriptor
53 /// Extract the raw file descriptor, without taking any ownership.
54 fn as_raw_fd(&self) -> Fd;
57 impl AsRawFd for old_io::fs::File {
58 fn as_raw_fd(&self) -> Fd {
63 impl AsRawFd for fs::File {
64 fn as_raw_fd(&self) -> Fd {
65 self.as_inner().fd().raw()
69 impl AsRawFd for old_io::pipe::PipeStream {
70 fn as_raw_fd(&self) -> Fd {
75 impl AsRawFd for old_io::net::pipe::UnixStream {
76 fn as_raw_fd(&self) -> Fd {
81 impl AsRawFd for old_io::net::pipe::UnixListener {
82 fn as_raw_fd(&self) -> Fd {
87 impl AsRawFd for old_io::net::pipe::UnixAcceptor {
88 fn as_raw_fd(&self) -> Fd {
93 impl AsRawFd for old_io::net::tcp::TcpStream {
94 fn as_raw_fd(&self) -> Fd {
99 impl AsRawFd for old_io::net::tcp::TcpListener {
100 fn as_raw_fd(&self) -> Fd {
105 impl AsRawFd for old_io::net::tcp::TcpAcceptor {
106 fn as_raw_fd(&self) -> Fd {
111 impl AsRawFd for old_io::net::udp::UdpSocket {
112 fn as_raw_fd(&self) -> Fd {
117 impl AsRawFd for net::TcpStream {
118 fn as_raw_fd(&self) -> Fd { *self.as_inner().socket().as_inner() }
120 impl AsRawFd for net::TcpListener {
121 fn as_raw_fd(&self) -> Fd { *self.as_inner().socket().as_inner() }
123 impl AsRawFd for net::UdpSocket {
124 fn as_raw_fd(&self) -> Fd { *self.as_inner().socket().as_inner() }
127 ////////////////////////////////////////////////////////////////////////////////
128 // OsString and OsStr
129 ////////////////////////////////////////////////////////////////////////////////
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;
136 /// Yield the underlying byte vector of this `OsString`.
137 fn into_vec(self) -> Vec<u8>;
140 impl OsStringExt for OsString {
141 fn from_vec(vec: Vec<u8>) -> OsString {
142 FromInner::from_inner(Buf { inner: vec })
145 fn into_vec(self) -> Vec<u8> {
146 self.into_inner().inner
150 /// Unix-specific extensions to `OsStr`.
152 fn from_bytes(slice: &[u8]) -> &OsStr;
154 /// Get the underlying byte view of the `OsStr` slice.
155 fn as_bytes(&self) -> &[u8];
157 /// Convert the `OsStr` slice into a `CString`.
158 fn to_cstring(&self) -> Result<CString, NulError>;
161 impl OsStrExt for OsStr {
162 fn from_bytes(slice: &[u8]) -> &OsStr {
163 unsafe { mem::transmute(slice) }
165 fn as_bytes(&self) -> &[u8] {
166 &self.as_inner().inner
169 fn to_cstring(&self) -> Result<CString, NulError> {
170 CString::new(self.as_bytes())
174 // Unix-specific extensions to `Permissions`
175 pub trait PermissionsExt {
176 fn set_mode(&mut self, mode: i32);
179 impl PermissionsExt for Permissions {
180 fn set_mode(&mut self, mode: i32) {
181 *self = FromInner::from_inner(FromInner::from_inner(mode));
185 // Unix-specific extensions to `OpenOptions`
186 pub trait OpenOptionsExt {
187 /// Set the mode bits that a new file will be created with.
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;
194 impl OpenOptionsExt for OpenOptions {
195 fn mode(&mut self, mode: i32) -> &mut OpenOptions {
196 self.as_inner_mut().mode(mode); self
200 ////////////////////////////////////////////////////////////////////////////////
201 // Process and Command
202 ////////////////////////////////////////////////////////////////////////////////
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;
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;
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);
222 fn gid(&mut self, id: gid_t) -> &mut process::Command {
223 self.as_inner_mut().gid = Some(id);
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>;
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),
243 ////////////////////////////////////////////////////////////////////////////////
245 ////////////////////////////////////////////////////////////////////////////////
247 /// A prelude for conveniently writing platform-specific code.
249 /// Includes all extension traits, and some important type definitions.
252 pub use super::{Fd, AsRawFd, OsStrExt, OsStringExt, PermissionsExt};
254 pub use super::{CommandExt, ExitStatusExt};