Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libs: add platform-specific APIs to extract file descriptors, SOCKETs, HANDLEs, etc from std::io #19169

Merged
merged 3 commits into from
Nov 26, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/libstd/io/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ pub struct File {
last_nread: int,
}

impl sys_common::AsFileDesc for File {
fn as_fd(&self) -> &fs_imp::FileDesc {
impl sys_common::AsInner<fs_imp::FileDesc> for File {
fn as_inner(&self) -> &fs_imp::FileDesc {
&self.fd
}
}
Expand Down
20 changes: 20 additions & 0 deletions src/libstd/io/net/pipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ use sys::pipe::UnixStream as UnixStreamImp;
use sys::pipe::UnixListener as UnixListenerImp;
use sys::pipe::UnixAcceptor as UnixAcceptorImp;

use sys_common;

/// A stream which communicates over a named pipe.
pub struct UnixStream {
inner: UnixStreamImp,
Expand Down Expand Up @@ -145,6 +147,12 @@ impl Writer for UnixStream {
}
}

impl sys_common::AsInner<UnixStreamImp> for UnixStream {
fn as_inner(&self) -> &UnixStreamImp {
&self.inner
}
}

/// A value that can listen for incoming named pipe connection requests.
pub struct UnixListener {
/// The internal, opaque runtime Unix listener.
Expand Down Expand Up @@ -186,6 +194,12 @@ impl Listener<UnixStream, UnixAcceptor> for UnixListener {
}
}

impl sys_common::AsInner<UnixListenerImp> for UnixListener {
fn as_inner(&self) -> &UnixListenerImp {
&self.inner
}
}

/// A value that can accept named pipe connections, returned from `listen()`.
pub struct UnixAcceptor {
/// The internal, opaque runtime Unix acceptor.
Expand Down Expand Up @@ -247,6 +261,12 @@ impl Clone for UnixAcceptor {
}
}

impl sys_common::AsInner<UnixAcceptorImp> for UnixAcceptor {
fn as_inner(&self) -> &UnixAcceptorImp {
&self.inner
}
}

#[cfg(test)]
#[allow(experimental)]
mod tests {
Expand Down
20 changes: 20 additions & 0 deletions src/libstd/io/net/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ use sys::tcp::TcpStream as TcpStreamImp;
use sys::tcp::TcpListener as TcpListenerImp;
use sys::tcp::TcpAcceptor as TcpAcceptorImp;

use sys_common;

/// A structure which represents a TCP stream between a local socket and a
/// remote socket.
///
Expand Down Expand Up @@ -256,6 +258,12 @@ impl Writer for TcpStream {
}
}

impl sys_common::AsInner<TcpStreamImp> for TcpStream {
fn as_inner(&self) -> &TcpStreamImp {
&self.inner
}
}

/// A structure representing a socket server. This listener is used to create a
/// `TcpAcceptor` which can be used to accept sockets on a local port.
///
Expand Down Expand Up @@ -325,6 +333,12 @@ impl Listener<TcpStream, TcpAcceptor> for TcpListener {
}
}

impl sys_common::AsInner<TcpListenerImp> for TcpListener {
fn as_inner(&self) -> &TcpListenerImp {
&self.inner
}
}

/// The accepting half of a TCP socket server. This structure is created through
/// a `TcpListener`'s `listen` method, and this object can be used to accept new
/// `TcpStream` instances.
Expand Down Expand Up @@ -452,6 +466,12 @@ impl Clone for TcpAcceptor {
}
}

impl sys_common::AsInner<TcpAcceptorImp> for TcpAcceptor {
fn as_inner(&self) -> &TcpAcceptorImp {
&self.inner
}
}

#[cfg(test)]
#[allow(experimental)]
mod test {
Expand Down
7 changes: 7 additions & 0 deletions src/libstd/io/net/udp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use io::{Reader, Writer, IoResult};
use option::Option;
use result::{Ok, Err};
use sys::udp::UdpSocket as UdpSocketImp;
use sys_common;

/// A User Datagram Protocol socket.
///
Expand Down Expand Up @@ -184,6 +185,12 @@ impl Clone for UdpSocket {
}
}

impl sys_common::AsInner<UdpSocketImp> for UdpSocket {
fn as_inner(&self) -> &UdpSocketImp {
&self.inner
}
}

/// A type that allows convenient usage of a UDP stream connected to one
/// address via the `Reader` and `Writer` traits.
///
Expand Down
4 changes: 2 additions & 2 deletions src/libstd/io/pipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ impl PipeStream {
}
}

impl sys_common::AsFileDesc for PipeStream {
fn as_fd(&self) -> &sys::fs::FileDesc {
impl sys_common::AsInner<sys::fs::FileDesc> for PipeStream {
fn as_inner(&self) -> &sys::fs::FileDesc {
&*self.inner
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/libstd/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ use vec::Vec;
#[cfg(unix)] use c_str::ToCStr;
#[cfg(unix)] use libc::c_char;

#[cfg(unix)]
pub use sys::ext as unix;
#[cfg(windows)]
pub use sys::ext as windows;

/// Get the number of cores available
pub fn num_cpus() -> uint {
unsafe {
Expand Down
9 changes: 4 additions & 5 deletions src/libstd/sys/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

use io::{mod, IoError, IoResult};
use prelude::*;
use sys::{last_error, retry, fs};
use sys::{last_error, retry};
use c_str::CString;
use num::Int;
use path::BytesContainer;
Expand Down Expand Up @@ -83,10 +83,9 @@ pub fn keep_going(data: &[u8], f: |*const u8, uint| -> i64) -> i64 {
return (origamt - amt) as i64;
}

// traits for extracting representations from

pub trait AsFileDesc {
fn as_fd(&self) -> &fs::FileDesc;
// A trait for extracting representations from std::io types
pub trait AsInner<Inner> {
fn as_inner(&self) -> &Inner;
}

pub trait ProcessConfig<K: BytesContainer, V: BytesContainer> {
Expand Down
107 changes: 107 additions & 0 deletions src/libstd/sys/unix/ext.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Experimental extensions to `std` for Unix platforms.
//!
//! For now, this module is limited to extracting file descriptors,
//! but its functionality will grow over time.
//!
//! # Example
//!
//! ```rust,ignore
//! #![feature(globs)]
//!
//! use std::io::fs::File;
//! use std::os::unix::prelude::*;
//!
//! fn main() {
//! let f = File::create(&Path::new("foo.txt")).unwrap();
//! let fd = f.as_raw_fd();
//!
//! // use fd with native unix bindings
//! }
//! ```

#![experimental]

use sys_common::AsInner;
use libc;

use io;

/// Raw file descriptors.
pub type Fd = libc::c_int;

/// Extract raw file descriptor
pub trait AsRawFd {
/// Extract the raw file descriptor, without taking any ownership.
fn as_raw_fd(&self) -> Fd;
}

impl AsRawFd for io::fs::File {
fn as_raw_fd(&self) -> Fd {
self.as_inner().fd()
}
}

impl AsRawFd for io::pipe::PipeStream {
fn as_raw_fd(&self) -> Fd {
self.as_inner().fd()
}
}

impl AsRawFd for io::net::pipe::UnixStream {
fn as_raw_fd(&self) -> Fd {
self.as_inner().fd()
}
}

impl AsRawFd for io::net::pipe::UnixListener {
fn as_raw_fd(&self) -> Fd {
self.as_inner().fd()
}
}

impl AsRawFd for io::net::pipe::UnixAcceptor {
fn as_raw_fd(&self) -> Fd {
self.as_inner().fd()
}
}

impl AsRawFd for io::net::tcp::TcpStream {
fn as_raw_fd(&self) -> Fd {
self.as_inner().fd()
}
}

impl AsRawFd for io::net::tcp::TcpListener {
fn as_raw_fd(&self) -> Fd {
self.as_inner().fd()
}
}

impl AsRawFd for io::net::tcp::TcpAcceptor {
fn as_raw_fd(&self) -> Fd {
self.as_inner().fd()
}
}

impl AsRawFd for io::net::udp::UdpSocket {
fn as_raw_fd(&self) -> Fd {
self.as_inner().fd()
}
}

/// A prelude for conveniently writing platform-specific code.
///
/// Includes all extension traits, and some important type definitions.
pub mod prelude {
pub use super::{Fd, AsRawFd};
}
1 change: 1 addition & 0 deletions src/libstd/sys/unix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ macro_rules! helper_init( (static $name:ident: Helper<$m:ty>) => (
) )

pub mod c;
pub mod ext;
pub mod fs;
pub mod os;
pub mod tcp;
Expand Down
6 changes: 3 additions & 3 deletions src/libstd/sys/unix/pipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ impl UnixStream {
}
}

fn fd(&self) -> fd_t { self.inner.fd }
pub fn fd(&self) -> fd_t { self.inner.fd }

#[cfg(target_os = "linux")]
fn lock_nonblocking(&self) {}
Expand Down Expand Up @@ -222,7 +222,7 @@ impl UnixListener {
})
}

fn fd(&self) -> fd_t { self.inner.fd }
pub fn fd(&self) -> fd_t { self.inner.fd }

pub fn listen(self) -> IoResult<UnixAcceptor> {
match unsafe { libc::listen(self.fd(), 128) } {
Expand Down Expand Up @@ -260,7 +260,7 @@ struct AcceptorInner {
}

impl UnixAcceptor {
fn fd(&self) -> fd_t { self.inner.listener.fd() }
pub fn fd(&self) -> fd_t { self.inner.listener.fd() }

pub fn accept(&mut self) -> IoResult<UnixStream> {
let deadline = if self.deadline == 0 {None} else {Some(self.deadline)};
Expand Down
6 changes: 3 additions & 3 deletions src/libstd/sys/unix/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use hash::Hash;
use sys::{mod, retry, c, wouldblock, set_nonblocking, ms_to_timeval};
use sys::fs::FileDesc;
use sys_common::helper_thread::Helper;
use sys_common::{AsFileDesc, mkerr_libc, timeout};
use sys_common::{AsInner, mkerr_libc, timeout};

pub use sys_common::ProcessConfig;

Expand Down Expand Up @@ -56,7 +56,7 @@ impl Process {
pub fn spawn<K, V, C, P>(cfg: &C, in_fd: Option<P>,
out_fd: Option<P>, err_fd: Option<P>)
-> IoResult<Process>
where C: ProcessConfig<K, V>, P: AsFileDesc,
where C: ProcessConfig<K, V>, P: AsInner<FileDesc>,
K: BytesContainer + Eq + Hash, V: BytesContainer
{
use libc::funcs::posix88::unistd::{fork, dup2, close, chdir, execvp};
Expand Down Expand Up @@ -183,7 +183,7 @@ impl Process {
libc::open(devnull.as_ptr(), flags, 0)
}
Some(obj) => {
let fd = obj.as_fd().fd();
let fd = obj.as_inner().fd();
// Leak the memory and the file descriptor. We're in the
// child now an all our resources are going to be
// cleaned up very soon
Expand Down
Loading