diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 2c78b289431..e5f2fcbae83 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -24,8 +24,8 @@ use ffi::OsString; use io::{self, SeekFrom, Seek, Read, Write}; use path::{Path, PathBuf}; use sys::fs as fs_imp; -use sys_common::{AsInnerMut, FromInner, AsInner}; use sys_common::io::read_to_end_uninitialized; +use sys_common::{AsInnerMut, FromInner, AsInner, IntoInner}; use vec::Vec; /// A reference to an open file on the filesystem. @@ -317,6 +317,11 @@ impl FromInner for File { File { inner: f } } } +impl IntoInner for File { + fn into_inner(self) -> fs_imp::File { + self.inner + } +} impl fmt::Debug for File { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs index 66c8403b268..c410233df92 100644 --- a/src/libstd/net/tcp.rs +++ b/src/libstd/net/tcp.rs @@ -17,9 +17,9 @@ use io::prelude::*; use fmt; use io; use net::{ToSocketAddrs, SocketAddr, Shutdown}; -use sys_common::net as net_imp; -use sys_common::{AsInner, FromInner}; use sys_common::io::read_to_end_uninitialized; +use sys_common::net as net_imp; +use sys_common::{AsInner, FromInner, IntoInner}; use time::Duration; /// A structure which represents a TCP stream between a local socket and a @@ -220,6 +220,10 @@ impl FromInner for TcpStream { fn from_inner(inner: net_imp::TcpStream) -> TcpStream { TcpStream(inner) } } +impl IntoInner for TcpStream { + fn into_inner(self) -> net_imp::TcpStream { self.0 } +} + impl fmt::Debug for TcpStream { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.0.fmt(f) @@ -298,6 +302,10 @@ impl FromInner for TcpListener { } } +impl IntoInner for TcpListener { + fn into_inner(self) -> net_imp::TcpListener { self.0 } +} + impl fmt::Debug for TcpListener { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.0.fmt(f) diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs index 0545175d9ae..a98ccc38735 100644 --- a/src/libstd/net/udp.rs +++ b/src/libstd/net/udp.rs @@ -17,7 +17,7 @@ use fmt; use io::{self, Error, ErrorKind}; use net::{ToSocketAddrs, SocketAddr, IpAddr}; use sys_common::net as net_imp; -use sys_common::{AsInner, FromInner}; +use sys_common::{AsInner, FromInner, IntoInner}; use time::Duration; /// A User Datagram Protocol socket. @@ -174,6 +174,10 @@ impl FromInner for UdpSocket { fn from_inner(inner: net_imp::UdpSocket) -> UdpSocket { UdpSocket(inner) } } +impl IntoInner for UdpSocket { + fn into_inner(self) -> net_imp::UdpSocket { self.0 } +} + impl fmt::Debug for UdpSocket { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.0.fmt(f) diff --git a/src/libstd/process.rs b/src/libstd/process.rs index a8127b3200f..3471805b2bc 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -23,7 +23,7 @@ use path; use sync::mpsc::{channel, Receiver}; use sys::pipe::{self, AnonPipe}; use sys::process as imp; -use sys_common::{AsInner, AsInnerMut, FromInner}; +use sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; use thread; /// Representation of a running or exited child process. @@ -71,6 +71,10 @@ impl AsInner for Child { fn as_inner(&self) -> &imp::Process { &self.handle } } +impl IntoInner for Child { + fn into_inner(self) -> imp::Process { self.handle } +} + /// A handle to a child procesess's stdin #[stable(feature = "process", since = "1.0.0")] pub struct ChildStdin { @@ -92,6 +96,10 @@ impl AsInner for ChildStdin { fn as_inner(&self) -> &AnonPipe { &self.inner } } +impl IntoInner for ChildStdin { + fn into_inner(self) -> AnonPipe { self.inner } +} + /// A handle to a child procesess's stdout #[stable(feature = "process", since = "1.0.0")] pub struct ChildStdout { @@ -109,6 +117,10 @@ impl AsInner for ChildStdout { fn as_inner(&self) -> &AnonPipe { &self.inner } } +impl IntoInner for ChildStdout { + fn into_inner(self) -> AnonPipe { self.inner } +} + /// A handle to a child procesess's stderr #[stable(feature = "process", since = "1.0.0")] pub struct ChildStderr { @@ -126,6 +138,10 @@ impl AsInner for ChildStderr { fn as_inner(&self) -> &AnonPipe { &self.inner } } +impl IntoInner for ChildStderr { + fn into_inner(self) -> AnonPipe { self.inner } +} + /// The `Command` type acts as a process builder, providing fine-grained control /// over how a new process should be spawned. A default configuration can be /// generated using `Command::new(program)`, where `program` gives a path to the diff --git a/src/libstd/sys/common/net.rs b/src/libstd/sys/common/net.rs index 5890e6a7889..6dd222b8f6e 100644 --- a/src/libstd/sys/common/net.rs +++ b/src/libstd/sys/common/net.rs @@ -184,6 +184,8 @@ impl TcpStream { pub fn socket(&self) -> &Socket { &self.inner } + pub fn into_socket(self) -> Socket { self.inner } + pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> { setsockopt(&self.inner, libc::IPPROTO_TCP, libc::TCP_NODELAY, nodelay as c_int) @@ -336,6 +338,8 @@ impl TcpListener { pub fn socket(&self) -> &Socket { &self.inner } + pub fn into_socket(self) -> Socket { self.inner } + pub fn socket_addr(&self) -> io::Result { sockname(|buf, len| unsafe { libc::getsockname(*self.inner.as_inner(), buf, len) @@ -396,6 +400,8 @@ impl UdpSocket { pub fn socket(&self) -> &Socket { &self.inner } + pub fn into_socket(self) -> Socket { self.inner } + pub fn socket_addr(&self) -> io::Result { sockname(|buf, len| unsafe { libc::getsockname(*self.inner.as_inner(), buf, len) diff --git a/src/libstd/sys/unix/ext/io.rs b/src/libstd/sys/unix/ext/io.rs index 79e59ddab5b..580d2dbcf74 100644 --- a/src/libstd/sys/unix/ext/io.rs +++ b/src/libstd/sys/unix/ext/io.rs @@ -16,7 +16,7 @@ use fs; use net; use os::raw; use sys; -use sys_common::{self, AsInner, FromInner}; +use sys_common::{self, AsInner, FromInner, IntoInner}; /// Raw file descriptors. #[stable(feature = "rust1", since = "1.0.0")] @@ -59,6 +59,18 @@ pub trait FromRawFd { unsafe fn from_raw_fd(fd: RawFd) -> Self; } +/// A trait to express the ability to consume an object and acquire ownership of +/// its raw file descriptor. +#[unstable(feature = "into_raw_os", reason = "recently added API")] +pub trait IntoRawFd { + /// Consumes this object, returning the raw underlying file descriptor. + /// + /// This function **transfers ownership** of the underlying file descriptor + /// to the caller. Callers are then the unique owners of the file descriptor + /// and must close the descriptor once it's no longer needed. + fn into_raw_fd(self) -> RawFd; +} + #[stable(feature = "rust1", since = "1.0.0")] impl AsRawFd for fs::File { fn as_raw_fd(&self) -> RawFd { @@ -71,6 +83,11 @@ impl FromRawFd for fs::File { fs::File::from_inner(sys::fs::File::from_inner(fd)) } } +impl IntoRawFd for fs::File { + fn into_raw_fd(self) -> RawFd { + self.into_inner().into_fd().into_raw() + } +} #[stable(feature = "rust1", since = "1.0.0")] impl AsRawFd for net::TcpStream { @@ -106,3 +123,19 @@ impl FromRawFd for net::UdpSocket { net::UdpSocket::from_inner(sys_common::net::UdpSocket::from_inner(socket)) } } + +impl IntoRawFd for net::TcpStream { + fn into_raw_fd(self) -> RawFd { + self.into_inner().into_socket().into_inner() + } +} +impl IntoRawFd for net::TcpListener { + fn into_raw_fd(self) -> RawFd { + self.into_inner().into_socket().into_inner() + } +} +impl IntoRawFd for net::UdpSocket { + fn into_raw_fd(self) -> RawFd { + self.into_inner().into_socket().into_inner() + } +} diff --git a/src/libstd/sys/unix/ext/process.rs b/src/libstd/sys/unix/ext/process.rs index cfe7a1f2dda..63adae17581 100644 --- a/src/libstd/sys/unix/ext/process.rs +++ b/src/libstd/sys/unix/ext/process.rs @@ -13,11 +13,11 @@ #![stable(feature = "rust1", since = "1.0.0")] use os::unix::raw::{uid_t, gid_t}; -use os::unix::io::{FromRawFd, RawFd, AsRawFd}; +use os::unix::io::{FromRawFd, RawFd, AsRawFd, IntoRawFd}; use prelude::v1::*; use process; use sys; -use sys_common::{AsInnerMut, AsInner, FromInner}; +use sys_common::{AsInnerMut, AsInner, FromInner, IntoInner}; /// Unix-specific extensions to the `std::process::Command` builder #[stable(feature = "rust1", since = "1.0.0")] @@ -92,3 +92,21 @@ impl AsRawFd for process::ChildStderr { self.as_inner().fd().raw() } } + +impl IntoRawFd for process::ChildStdin { + fn into_raw_fd(self) -> RawFd { + self.into_inner().into_fd().into_raw() + } +} + +impl IntoRawFd for process::ChildStdout { + fn into_raw_fd(self) -> RawFd { + self.into_inner().into_fd().into_raw() + } +} + +impl IntoRawFd for process::ChildStderr { + fn into_raw_fd(self) -> RawFd { + self.into_inner().into_fd().into_raw() + } +} diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index 867cdcbab94..0c99a30f107 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -331,6 +331,8 @@ impl File { } pub fn fd(&self) -> &FileDesc { &self.0 } + + pub fn into_fd(self) -> FileDesc { self.0 } } impl DirBuilder { diff --git a/src/libstd/sys/unix/net.rs b/src/libstd/sys/unix/net.rs index 1f40c18be2f..37eb7fd2ac8 100644 --- a/src/libstd/sys/unix/net.rs +++ b/src/libstd/sys/unix/net.rs @@ -17,7 +17,7 @@ use str; use sys::c; use net::SocketAddr; use sys::fd::FileDesc; -use sys_common::{AsInner, FromInner}; +use sys_common::{AsInner, FromInner, IntoInner}; use sys_common::net::{getsockopt, setsockopt}; use time::Duration; @@ -127,3 +127,7 @@ impl AsInner for Socket { impl FromInner for Socket { fn from_inner(fd: c_int) -> Socket { Socket(FileDesc::new(fd)) } } + +impl IntoInner for Socket { + fn into_inner(self) -> c_int { self.0.into_raw() } +} diff --git a/src/libstd/sys/unix/pipe.rs b/src/libstd/sys/unix/pipe.rs index 946857c05bc..140f0c042ba 100644 --- a/src/libstd/sys/unix/pipe.rs +++ b/src/libstd/sys/unix/pipe.rs @@ -46,4 +46,5 @@ impl AnonPipe { pub fn raw(&self) -> libc::c_int { self.0.raw() } pub fn fd(&self) -> &FileDesc { &self.0 } + pub fn into_fd(self) -> FileDesc { self.0 } } diff --git a/src/libstd/sys/windows/ext/io.rs b/src/libstd/sys/windows/ext/io.rs index f4717eb2425..185f1abe64b 100644 --- a/src/libstd/sys/windows/ext/io.rs +++ b/src/libstd/sys/windows/ext/io.rs @@ -13,7 +13,7 @@ use fs; use os::windows::raw; use net; -use sys_common::{self, AsInner, FromInner}; +use sys_common::{self, AsInner, FromInner, IntoInner}; use sys; /// Raw HANDLEs. @@ -50,6 +50,18 @@ pub trait FromRawHandle { unsafe fn from_raw_handle(handle: RawHandle) -> Self; } +/// A trait to express the ability to consume an object and acquire ownership of +/// its raw `HANDLE`. +#[unstable(feature = "into_raw_os", reason = "recently added API")] +pub trait IntoRawHandle { + /// Consumes this object, returning the raw underlying handle. + /// + /// This function **transfers ownership** of the underlying handle to the + /// caller. Callers are then the unique owners of the handle and must close + /// it once it's no longer needed. + fn into_raw_handle(self) -> RawHandle; +} + #[stable(feature = "rust1", since = "1.0.0")] impl AsRawHandle for fs::File { fn as_raw_handle(&self) -> RawHandle { @@ -65,6 +77,12 @@ impl FromRawHandle for fs::File { } } +impl IntoRawHandle for fs::File { + fn into_raw_handle(self) -> RawHandle { + self.into_inner().into_handle().into_raw() as *mut _ + } +} + /// Extract raw sockets. #[stable(feature = "rust1", since = "1.0.0")] pub trait AsRawSocket { @@ -90,6 +108,18 @@ pub trait FromRawSocket { unsafe fn from_raw_socket(sock: RawSocket) -> Self; } +/// A trait to express the ability to consume an object and acquire ownership of +/// its raw `SOCKET`. +#[unstable(feature = "into_raw_os", reason = "recently added API")] +pub trait IntoRawSocket { + /// Consumes this object, returning the raw underlying socket. + /// + /// This function **transfers ownership** of the underlying socket to the + /// caller. Callers are then the unique owners of the socket and must close + /// it once it's no longer needed. + fn into_raw_socket(self) -> RawSocket; +} + #[stable(feature = "rust1", since = "1.0.0")] impl AsRawSocket for net::TcpStream { fn as_raw_socket(&self) -> RawSocket { @@ -130,3 +160,21 @@ impl FromRawSocket for net::UdpSocket { net::UdpSocket::from_inner(sys_common::net::UdpSocket::from_inner(sock)) } } + +impl IntoRawSocket for net::TcpStream { + fn into_raw_socket(self) -> RawSocket { + self.into_inner().into_socket().into_inner() + } +} + +impl IntoRawSocket for net::TcpListener { + fn into_raw_socket(self) -> RawSocket { + self.into_inner().into_socket().into_inner() + } +} + +impl IntoRawSocket for net::UdpSocket { + fn into_raw_socket(self) -> RawSocket { + self.into_inner().into_socket().into_inner() + } +} diff --git a/src/libstd/sys/windows/ext/process.rs b/src/libstd/sys/windows/ext/process.rs index 6f59be2687a..fde21e9a798 100644 --- a/src/libstd/sys/windows/ext/process.rs +++ b/src/libstd/sys/windows/ext/process.rs @@ -12,10 +12,10 @@ #![stable(feature = "process_extensions", since = "1.2.0")] -use os::windows::io::{FromRawHandle, RawHandle, AsRawHandle}; +use os::windows::io::{FromRawHandle, RawHandle, AsRawHandle, IntoRawHandle}; use process; use sys; -use sys_common::{AsInner, FromInner}; +use sys_common::{AsInner, FromInner, IntoInner}; #[stable(feature = "process_extensions", since = "1.2.0")] impl FromRawHandle for process::Stdio { @@ -32,6 +32,12 @@ impl AsRawHandle for process::Child { } } +impl IntoRawHandle for process::Child { + fn into_raw_handle(self) -> RawHandle { + self.into_inner().into_handle().into_raw() as *mut _ + } +} + #[stable(feature = "process_extensions", since = "1.2.0")] impl AsRawHandle for process::ChildStdin { fn as_raw_handle(&self) -> RawHandle { @@ -52,3 +58,21 @@ impl AsRawHandle for process::ChildStderr { self.as_inner().handle().raw() as *mut _ } } + +impl IntoRawHandle for process::ChildStdin { + fn into_raw_handle(self) -> RawHandle { + self.into_inner().into_handle().into_raw() as *mut _ + } +} + +impl IntoRawHandle for process::ChildStdout { + fn into_raw_handle(self) -> RawHandle { + self.into_inner().into_handle().into_raw() as *mut _ + } +} + +impl IntoRawHandle for process::ChildStderr { + fn into_raw_handle(self) -> RawHandle { + self.into_inner().into_handle().into_raw() as *mut _ + } +} diff --git a/src/libstd/sys/windows/fs.rs b/src/libstd/sys/windows/fs.rs index 890cc455d5d..5dd84e9f71e 100644 --- a/src/libstd/sys/windows/fs.rs +++ b/src/libstd/sys/windows/fs.rs @@ -319,6 +319,8 @@ impl File { pub fn handle(&self) -> &Handle { &self.handle } + pub fn into_handle(self) -> Handle { self.handle } + fn reparse_point<'a>(&self, space: &'a mut [u8; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE]) -> io::Result<(libc::DWORD, &'a c::REPARSE_DATA_BUFFER)> { @@ -357,8 +359,6 @@ impl File { Ok(PathBuf::from(OsString::from_wide(subst))) } } - - pub fn into_handle(self) -> Handle { self.handle } } impl FromInner for File { diff --git a/src/libstd/sys/windows/net.rs b/src/libstd/sys/windows/net.rs index b765bc6e500..d58355ed1fe 100644 --- a/src/libstd/sys/windows/net.rs +++ b/src/libstd/sys/windows/net.rs @@ -21,7 +21,7 @@ use rt; use sync::Once; use sys; use sys::c; -use sys_common::{AsInner, FromInner}; +use sys_common::{AsInner, FromInner, IntoInner}; use sys_common::net::{setsockopt, getsockopt}; use time::Duration; @@ -184,3 +184,11 @@ impl AsInner for Socket { impl FromInner for Socket { fn from_inner(sock: libc::SOCKET) -> Socket { Socket(sock) } } + +impl IntoInner for Socket { + fn into_inner(self) -> libc::SOCKET { + let ret = self.0; + mem::forget(self); + ret + } +} diff --git a/src/libstd/sys/windows/pipe.rs b/src/libstd/sys/windows/pipe.rs index b2a6607314a..a7ece66e0f1 100644 --- a/src/libstd/sys/windows/pipe.rs +++ b/src/libstd/sys/windows/pipe.rs @@ -37,6 +37,7 @@ pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> { impl AnonPipe { pub fn handle(&self) -> &Handle { &self.inner } + pub fn into_handle(self) -> Handle { self.inner } pub fn raw(&self) -> libc::HANDLE { self.inner.raw() } diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs index 0b0268d4746..ca33e11eea0 100644 --- a/src/libstd/sys/windows/process.rs +++ b/src/libstd/sys/windows/process.rs @@ -220,6 +220,8 @@ impl Process { } pub fn handle(&self) -> &Handle { &self.handle } + + pub fn into_handle(self) -> Handle { self.handle } } #[derive(PartialEq, Eq, Clone, Copy, Debug)]