Skip to content

Commit 7e9e389

Browse files
committed
std: Add IntoRaw{Fd,Handle,Socket} traits
This commit is an implementation of [RFC 1174][rfc] which adds three new traits to the standard library: * `IntoRawFd` - implemented on Unix for all I/O types (files, sockets, etc) * `IntoRawHandle` - implemented on Windows for files, processes, etc * `IntoRawSocket` - implemented on Windows for networking types [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1174-into-raw-fd-socket-handle-traits.md Closes rust-lang#27062
1 parent 4e51763 commit 7e9e389

File tree

16 files changed

+195
-15
lines changed

16 files changed

+195
-15
lines changed

src/libstd/fs.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ use ffi::OsString;
2424
use io::{self, SeekFrom, Seek, Read, Write};
2525
use path::{Path, PathBuf};
2626
use sys::fs as fs_imp;
27-
use sys_common::{AsInnerMut, FromInner, AsInner};
2827
use sys_common::io::read_to_end_uninitialized;
28+
use sys_common::{AsInnerMut, FromInner, AsInner, IntoInner};
2929
use vec::Vec;
3030

3131
/// A reference to an open file on the filesystem.
@@ -317,6 +317,11 @@ impl FromInner<fs_imp::File> for File {
317317
File { inner: f }
318318
}
319319
}
320+
impl IntoInner<fs_imp::File> for File {
321+
fn into_inner(self) -> fs_imp::File {
322+
self.inner
323+
}
324+
}
320325

321326
impl fmt::Debug for File {
322327
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {

src/libstd/net/tcp.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ use io::prelude::*;
1717
use fmt;
1818
use io;
1919
use net::{ToSocketAddrs, SocketAddr, Shutdown};
20-
use sys_common::net as net_imp;
21-
use sys_common::{AsInner, FromInner};
2220
use sys_common::io::read_to_end_uninitialized;
21+
use sys_common::net as net_imp;
22+
use sys_common::{AsInner, FromInner, IntoInner};
2323
use time::Duration;
2424

2525
/// A structure which represents a TCP stream between a local socket and a
@@ -220,6 +220,10 @@ impl FromInner<net_imp::TcpStream> for TcpStream {
220220
fn from_inner(inner: net_imp::TcpStream) -> TcpStream { TcpStream(inner) }
221221
}
222222

223+
impl IntoInner<net_imp::TcpStream> for TcpStream {
224+
fn into_inner(self) -> net_imp::TcpStream { self.0 }
225+
}
226+
223227
impl fmt::Debug for TcpStream {
224228
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
225229
self.0.fmt(f)
@@ -298,6 +302,10 @@ impl FromInner<net_imp::TcpListener> for TcpListener {
298302
}
299303
}
300304

305+
impl IntoInner<net_imp::TcpListener> for TcpListener {
306+
fn into_inner(self) -> net_imp::TcpListener { self.0 }
307+
}
308+
301309
impl fmt::Debug for TcpListener {
302310
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
303311
self.0.fmt(f)

src/libstd/net/udp.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use fmt;
1717
use io::{self, Error, ErrorKind};
1818
use net::{ToSocketAddrs, SocketAddr, IpAddr};
1919
use sys_common::net as net_imp;
20-
use sys_common::{AsInner, FromInner};
20+
use sys_common::{AsInner, FromInner, IntoInner};
2121
use time::Duration;
2222

2323
/// A User Datagram Protocol socket.
@@ -174,6 +174,10 @@ impl FromInner<net_imp::UdpSocket> for UdpSocket {
174174
fn from_inner(inner: net_imp::UdpSocket) -> UdpSocket { UdpSocket(inner) }
175175
}
176176

177+
impl IntoInner<net_imp::UdpSocket> for UdpSocket {
178+
fn into_inner(self) -> net_imp::UdpSocket { self.0 }
179+
}
180+
177181
impl fmt::Debug for UdpSocket {
178182
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
179183
self.0.fmt(f)

src/libstd/process.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use path;
2323
use sync::mpsc::{channel, Receiver};
2424
use sys::pipe::{self, AnonPipe};
2525
use sys::process as imp;
26-
use sys_common::{AsInner, AsInnerMut, FromInner};
26+
use sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
2727
use thread;
2828

2929
/// Representation of a running or exited child process.
@@ -71,6 +71,10 @@ impl AsInner<imp::Process> for Child {
7171
fn as_inner(&self) -> &imp::Process { &self.handle }
7272
}
7373

74+
impl IntoInner<imp::Process> for Child {
75+
fn into_inner(self) -> imp::Process { self.handle }
76+
}
77+
7478
/// A handle to a child procesess's stdin
7579
#[stable(feature = "process", since = "1.0.0")]
7680
pub struct ChildStdin {
@@ -92,6 +96,10 @@ impl AsInner<AnonPipe> for ChildStdin {
9296
fn as_inner(&self) -> &AnonPipe { &self.inner }
9397
}
9498

99+
impl IntoInner<AnonPipe> for ChildStdin {
100+
fn into_inner(self) -> AnonPipe { self.inner }
101+
}
102+
95103
/// A handle to a child procesess's stdout
96104
#[stable(feature = "process", since = "1.0.0")]
97105
pub struct ChildStdout {
@@ -109,6 +117,10 @@ impl AsInner<AnonPipe> for ChildStdout {
109117
fn as_inner(&self) -> &AnonPipe { &self.inner }
110118
}
111119

120+
impl IntoInner<AnonPipe> for ChildStdout {
121+
fn into_inner(self) -> AnonPipe { self.inner }
122+
}
123+
112124
/// A handle to a child procesess's stderr
113125
#[stable(feature = "process", since = "1.0.0")]
114126
pub struct ChildStderr {
@@ -126,6 +138,10 @@ impl AsInner<AnonPipe> for ChildStderr {
126138
fn as_inner(&self) -> &AnonPipe { &self.inner }
127139
}
128140

141+
impl IntoInner<AnonPipe> for ChildStderr {
142+
fn into_inner(self) -> AnonPipe { self.inner }
143+
}
144+
129145
/// The `Command` type acts as a process builder, providing fine-grained control
130146
/// over how a new process should be spawned. A default configuration can be
131147
/// generated using `Command::new(program)`, where `program` gives a path to the

src/libstd/sys/common/net.rs

+6
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,8 @@ impl TcpStream {
184184

185185
pub fn socket(&self) -> &Socket { &self.inner }
186186

187+
pub fn into_socket(self) -> Socket { self.inner }
188+
187189
pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
188190
setsockopt(&self.inner, libc::IPPROTO_TCP, libc::TCP_NODELAY,
189191
nodelay as c_int)
@@ -336,6 +338,8 @@ impl TcpListener {
336338

337339
pub fn socket(&self) -> &Socket { &self.inner }
338340

341+
pub fn into_socket(self) -> Socket { self.inner }
342+
339343
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
340344
sockname(|buf, len| unsafe {
341345
libc::getsockname(*self.inner.as_inner(), buf, len)
@@ -396,6 +400,8 @@ impl UdpSocket {
396400

397401
pub fn socket(&self) -> &Socket { &self.inner }
398402

403+
pub fn into_socket(self) -> Socket { self.inner }
404+
399405
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
400406
sockname(|buf, len| unsafe {
401407
libc::getsockname(*self.inner.as_inner(), buf, len)

src/libstd/sys/unix/ext/io.rs

+34-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use fs;
1616
use net;
1717
use os::raw;
1818
use sys;
19-
use sys_common::{self, AsInner, FromInner};
19+
use sys_common::{self, AsInner, FromInner, IntoInner};
2020

2121
/// Raw file descriptors.
2222
#[stable(feature = "rust1", since = "1.0.0")]
@@ -59,6 +59,18 @@ pub trait FromRawFd {
5959
unsafe fn from_raw_fd(fd: RawFd) -> Self;
6060
}
6161

62+
/// A trait to express the ability to consume an object and acquire ownership of
63+
/// its raw file descriptor.
64+
#[unstable(feature = "into_raw_os", reason = "recently added API")]
65+
pub trait IntoRawFd {
66+
/// Consumes this object, returning the raw underlying file descriptor.
67+
///
68+
/// This function **transfers ownership** of the underlying file descriptor
69+
/// to the caller. Callers are then the unique owners of the file descriptor
70+
/// and must close the descriptor once it's no longer needed.
71+
fn into_raw_fd(self) -> RawFd;
72+
}
73+
6274
#[stable(feature = "rust1", since = "1.0.0")]
6375
impl AsRawFd for fs::File {
6476
fn as_raw_fd(&self) -> RawFd {
@@ -71,6 +83,11 @@ impl FromRawFd for fs::File {
7183
fs::File::from_inner(sys::fs::File::from_inner(fd))
7284
}
7385
}
86+
impl IntoRawFd for fs::File {
87+
fn into_raw_fd(self) -> RawFd {
88+
self.into_inner().into_fd().into_raw()
89+
}
90+
}
7491

7592
#[stable(feature = "rust1", since = "1.0.0")]
7693
impl AsRawFd for net::TcpStream {
@@ -106,3 +123,19 @@ impl FromRawFd for net::UdpSocket {
106123
net::UdpSocket::from_inner(sys_common::net::UdpSocket::from_inner(socket))
107124
}
108125
}
126+
127+
impl IntoRawFd for net::TcpStream {
128+
fn into_raw_fd(self) -> RawFd {
129+
self.into_inner().into_socket().into_inner()
130+
}
131+
}
132+
impl IntoRawFd for net::TcpListener {
133+
fn into_raw_fd(self) -> RawFd {
134+
self.into_inner().into_socket().into_inner()
135+
}
136+
}
137+
impl IntoRawFd for net::UdpSocket {
138+
fn into_raw_fd(self) -> RawFd {
139+
self.into_inner().into_socket().into_inner()
140+
}
141+
}

src/libstd/sys/unix/ext/process.rs

+20-2
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@
1313
#![stable(feature = "rust1", since = "1.0.0")]
1414

1515
use os::unix::raw::{uid_t, gid_t};
16-
use os::unix::io::{FromRawFd, RawFd, AsRawFd};
16+
use os::unix::io::{FromRawFd, RawFd, AsRawFd, IntoRawFd};
1717
use prelude::v1::*;
1818
use process;
1919
use sys;
20-
use sys_common::{AsInnerMut, AsInner, FromInner};
20+
use sys_common::{AsInnerMut, AsInner, FromInner, IntoInner};
2121

2222
/// Unix-specific extensions to the `std::process::Command` builder
2323
#[stable(feature = "rust1", since = "1.0.0")]
@@ -92,3 +92,21 @@ impl AsRawFd for process::ChildStderr {
9292
self.as_inner().fd().raw()
9393
}
9494
}
95+
96+
impl IntoRawFd for process::ChildStdin {
97+
fn into_raw_fd(self) -> RawFd {
98+
self.into_inner().into_fd().into_raw()
99+
}
100+
}
101+
102+
impl IntoRawFd for process::ChildStdout {
103+
fn into_raw_fd(self) -> RawFd {
104+
self.into_inner().into_fd().into_raw()
105+
}
106+
}
107+
108+
impl IntoRawFd for process::ChildStderr {
109+
fn into_raw_fd(self) -> RawFd {
110+
self.into_inner().into_fd().into_raw()
111+
}
112+
}

src/libstd/sys/unix/fs.rs

+2
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,8 @@ impl File {
331331
}
332332

333333
pub fn fd(&self) -> &FileDesc { &self.0 }
334+
335+
pub fn into_fd(self) -> FileDesc { self.0 }
334336
}
335337

336338
impl DirBuilder {

src/libstd/sys/unix/net.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use str;
1717
use sys::c;
1818
use net::SocketAddr;
1919
use sys::fd::FileDesc;
20-
use sys_common::{AsInner, FromInner};
20+
use sys_common::{AsInner, FromInner, IntoInner};
2121
use sys_common::net::{getsockopt, setsockopt};
2222
use time::Duration;
2323

@@ -127,3 +127,7 @@ impl AsInner<c_int> for Socket {
127127
impl FromInner<c_int> for Socket {
128128
fn from_inner(fd: c_int) -> Socket { Socket(FileDesc::new(fd)) }
129129
}
130+
131+
impl IntoInner<c_int> for Socket {
132+
fn into_inner(self) -> c_int { self.0.into_raw() }
133+
}

src/libstd/sys/unix/pipe.rs

+1
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,5 @@ impl AnonPipe {
4646

4747
pub fn raw(&self) -> libc::c_int { self.0.raw() }
4848
pub fn fd(&self) -> &FileDesc { &self.0 }
49+
pub fn into_fd(self) -> FileDesc { self.0 }
4950
}

src/libstd/sys/windows/ext/io.rs

+49-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
use fs;
1414
use os::windows::raw;
1515
use net;
16-
use sys_common::{self, AsInner, FromInner};
16+
use sys_common::{self, AsInner, FromInner, IntoInner};
1717
use sys;
1818

1919
/// Raw HANDLEs.
@@ -50,6 +50,18 @@ pub trait FromRawHandle {
5050
unsafe fn from_raw_handle(handle: RawHandle) -> Self;
5151
}
5252

53+
/// A trait to express the ability to consume an object and acquire ownership of
54+
/// its raw `HANDLE`.
55+
#[unstable(feature = "into_raw_os", reason = "recently added API")]
56+
pub trait IntoRawHandle {
57+
/// Consumes this object, returning the raw underlying handle.
58+
///
59+
/// This function **transfers ownership** of the underlying handle to the
60+
/// caller. Callers are then the unique owners of the handle and must close
61+
/// it once it's no longer needed.
62+
fn into_raw_handle(self) -> RawHandle;
63+
}
64+
5365
#[stable(feature = "rust1", since = "1.0.0")]
5466
impl AsRawHandle for fs::File {
5567
fn as_raw_handle(&self) -> RawHandle {
@@ -65,6 +77,12 @@ impl FromRawHandle for fs::File {
6577
}
6678
}
6779

80+
impl IntoRawHandle for fs::File {
81+
fn into_raw_handle(self) -> RawHandle {
82+
self.into_inner().into_handle().into_raw() as *mut _
83+
}
84+
}
85+
6886
/// Extract raw sockets.
6987
#[stable(feature = "rust1", since = "1.0.0")]
7088
pub trait AsRawSocket {
@@ -90,6 +108,18 @@ pub trait FromRawSocket {
90108
unsafe fn from_raw_socket(sock: RawSocket) -> Self;
91109
}
92110

111+
/// A trait to express the ability to consume an object and acquire ownership of
112+
/// its raw `SOCKET`.
113+
#[unstable(feature = "into_raw_os", reason = "recently added API")]
114+
pub trait IntoRawSocket {
115+
/// Consumes this object, returning the raw underlying socket.
116+
///
117+
/// This function **transfers ownership** of the underlying socket to the
118+
/// caller. Callers are then the unique owners of the socket and must close
119+
/// it once it's no longer needed.
120+
fn into_raw_socket(self) -> RawSocket;
121+
}
122+
93123
#[stable(feature = "rust1", since = "1.0.0")]
94124
impl AsRawSocket for net::TcpStream {
95125
fn as_raw_socket(&self) -> RawSocket {
@@ -130,3 +160,21 @@ impl FromRawSocket for net::UdpSocket {
130160
net::UdpSocket::from_inner(sys_common::net::UdpSocket::from_inner(sock))
131161
}
132162
}
163+
164+
impl IntoRawSocket for net::TcpStream {
165+
fn into_raw_socket(self) -> RawSocket {
166+
self.into_inner().into_socket().into_inner()
167+
}
168+
}
169+
170+
impl IntoRawSocket for net::TcpListener {
171+
fn into_raw_socket(self) -> RawSocket {
172+
self.into_inner().into_socket().into_inner()
173+
}
174+
}
175+
176+
impl IntoRawSocket for net::UdpSocket {
177+
fn into_raw_socket(self) -> RawSocket {
178+
self.into_inner().into_socket().into_inner()
179+
}
180+
}

0 commit comments

Comments
 (0)