auto merge of #19169 : aturon/rust/fds, r=alexcrichton
This PR adds some internal infrastructure to allow the private `std::sys` module to access internal representation details of `std::io`. It then exposes those details in two new, platform-specific API surfaces: `std::os::unix` and `std::os::windows`. To start with, these will provide the ability to extract file descriptors, HANDLEs, SOCKETs, and so on from `std::io` types. More functionality, and more specific platforms (e.g. `std::os::linux`) will be added over time. Closes #18897
This commit is contained in:
commit
61af402789
15 changed files with 287 additions and 19 deletions
100
src/libstd/sys/windows/ext.rs
Normal file
100
src/libstd/sys/windows/ext.rs
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
// 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 Windows.
|
||||
//!
|
||||
//! For now, this module is limited to extracting handles, file
|
||||
//! descriptors, and sockets, but its functionality will grow over
|
||||
//! time.
|
||||
|
||||
#![experimental]
|
||||
|
||||
use sys_common::AsInner;
|
||||
use libc;
|
||||
|
||||
use io;
|
||||
|
||||
/// Raw HANDLEs.
|
||||
pub type Handle = libc::HANDLE;
|
||||
|
||||
/// Raw SOCKETs.
|
||||
pub type Socket = libc::SOCKET;
|
||||
|
||||
/// Extract raw handles.
|
||||
pub trait AsRawHandle {
|
||||
/// Extract the raw handle, without taking any ownership.
|
||||
fn as_raw_handle(&self) -> Handle;
|
||||
}
|
||||
|
||||
impl AsRawHandle for io::fs::File {
|
||||
fn as_raw_handle(&self) -> Handle {
|
||||
self.as_inner().handle()
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRawHandle for io::pipe::PipeStream {
|
||||
fn as_raw_handle(&self) -> Handle {
|
||||
self.as_inner().handle()
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRawHandle for io::net::pipe::UnixStream {
|
||||
fn as_raw_handle(&self) -> Handle {
|
||||
self.as_inner().handle()
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRawHandle for io::net::pipe::UnixListener {
|
||||
fn as_raw_handle(&self) -> Handle {
|
||||
self.as_inner().handle()
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRawHandle for io::net::pipe::UnixAcceptor {
|
||||
fn as_raw_handle(&self) -> Handle {
|
||||
self.as_inner().handle()
|
||||
}
|
||||
}
|
||||
|
||||
/// Extract raw sockets.
|
||||
pub trait AsRawSocket {
|
||||
fn as_raw_socket(&self) -> Socket;
|
||||
}
|
||||
|
||||
impl AsRawSocket for io::net::tcp::TcpStream {
|
||||
fn as_raw_socket(&self) -> Socket {
|
||||
self.as_inner().fd()
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRawSocket for io::net::tcp::TcpListener {
|
||||
fn as_raw_socket(&self) -> Socket {
|
||||
self.as_inner().fd()
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRawSocket for io::net::tcp::TcpAcceptor {
|
||||
fn as_raw_socket(&self) -> Socket {
|
||||
self.as_inner().fd()
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRawSocket for io::net::udp::UdpSocket {
|
||||
fn as_raw_socket(&self) -> Socket {
|
||||
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::{Socket, Handle, AsRawSocket, AsRawHandle};
|
||||
}
|
||||
|
|
@ -34,6 +34,7 @@ macro_rules! helper_init( (static $name:ident: Helper<$m:ty>) => (
|
|||
) )
|
||||
|
||||
pub mod c;
|
||||
pub mod ext;
|
||||
pub mod fs;
|
||||
pub mod helper_signal;
|
||||
pub mod os;
|
||||
|
|
|
|||
|
|
@ -329,7 +329,7 @@ impl UnixStream {
|
|||
}
|
||||
}
|
||||
|
||||
fn handle(&self) -> libc::HANDLE { self.inner.handle }
|
||||
pub fn handle(&self) -> libc::HANDLE { self.inner.handle }
|
||||
|
||||
fn read_closed(&self) -> bool {
|
||||
self.inner.read_closed.load(atomic::SeqCst)
|
||||
|
|
@ -585,6 +585,10 @@ impl UnixListener {
|
|||
}),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn handle(&self) -> libc::HANDLE {
|
||||
self.handle
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for UnixListener {
|
||||
|
|
@ -729,6 +733,10 @@ impl UnixAcceptor {
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle(&self) -> libc::HANDLE {
|
||||
self.listener.handle()
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for UnixAcceptor {
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ use sys::fs;
|
|||
use sys::{mod, retry, c, wouldblock, set_nonblocking, ms_to_timeval, timer};
|
||||
use sys::fs::FileDesc;
|
||||
use sys_common::helper_thread::Helper;
|
||||
use sys_common::{AsFileDesc, mkerr_libc, timeout};
|
||||
use sys_common::{AsInner, mkerr_libc, timeout};
|
||||
|
||||
use io::fs::PathExtensions;
|
||||
use string::String;
|
||||
|
|
@ -105,7 +105,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::types::os::arch::extra::{DWORD, HANDLE, STARTUPINFO};
|
||||
|
|
@ -195,7 +195,7 @@ impl Process {
|
|||
}
|
||||
}
|
||||
Some(ref fd) => {
|
||||
let orig = get_osfhandle(fd.as_fd().fd()) as HANDLE;
|
||||
let orig = get_osfhandle(fd.as_inner().fd()) as HANDLE;
|
||||
if orig == INVALID_HANDLE_VALUE {
|
||||
return Err(super::last_error())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue