Skip to content

Commit d71264b

Browse files
committed
std: Make FromRawFd::from_raw_fd an unsafe method
As pointed out in [RFC issue 1043][rfc] it is quite useful to have the standard I/O types to provide the contract that they are the sole owner of the underlying object they represent. This guarantee enables writing safe interfaces like the `MemoryMap` API sketched out in that issue. [rfc]: rust-lang/rfcs#1043 As constructing objects from these raw handles may end up violating these ownership gurantees, the functions for construction are now marked unsafe. [breaking-change] Closes #1043
1 parent e326aa1 commit d71264b

File tree

2 files changed

+28
-13
lines changed

2 files changed

+28
-13
lines changed

src/libstd/sys/unix/ext.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,12 @@ pub mod io {
7474
/// descriptor. The returned object will take responsibility for closing
7575
/// it when the object goes out of scope.
7676
///
77-
/// Callers should normally only pass in a valid file descriptor to this
78-
/// method or otherwise methods will return errors.
79-
fn from_raw_fd(fd: RawFd) -> Self;
77+
/// This function is also unsafe as the primitives currently returned
78+
/// have the contract that they are the sole owner of the file
79+
/// descriptor they are wrapping. Usage of this function could
80+
/// accidentally allow violating this contract which can cause memory
81+
/// unsafety in code that relies on it being true.
82+
unsafe fn from_raw_fd(fd: RawFd) -> Self;
8083
}
8184

8285
#[allow(deprecated)]
@@ -95,7 +98,7 @@ pub mod io {
9598
}
9699
#[unstable(feature = "from_raw_os", reason = "trait is unstable")]
97100
impl FromRawFd for fs::File {
98-
fn from_raw_fd(fd: RawFd) -> fs::File {
101+
unsafe fn from_raw_fd(fd: RawFd) -> fs::File {
99102
fs::File::from_inner(sys::fs2::File::from_inner(fd))
100103
}
101104
}
@@ -179,21 +182,21 @@ pub mod io {
179182

180183
#[unstable(feature = "from_raw_os", reason = "trait is unstable")]
181184
impl FromRawFd for net::TcpStream {
182-
fn from_raw_fd(fd: RawFd) -> net::TcpStream {
185+
unsafe fn from_raw_fd(fd: RawFd) -> net::TcpStream {
183186
let socket = sys::net::Socket::from_inner(fd);
184187
net::TcpStream::from_inner(net2::TcpStream::from_inner(socket))
185188
}
186189
}
187190
#[unstable(feature = "from_raw_os", reason = "trait is unstable")]
188191
impl FromRawFd for net::TcpListener {
189-
fn from_raw_fd(fd: RawFd) -> net::TcpListener {
192+
unsafe fn from_raw_fd(fd: RawFd) -> net::TcpListener {
190193
let socket = sys::net::Socket::from_inner(fd);
191194
net::TcpListener::from_inner(net2::TcpListener::from_inner(socket))
192195
}
193196
}
194197
#[unstable(feature = "from_raw_os", reason = "trait is unstable")]
195198
impl FromRawFd for net::UdpSocket {
196-
fn from_raw_fd(fd: RawFd) -> net::UdpSocket {
199+
unsafe fn from_raw_fd(fd: RawFd) -> net::UdpSocket {
197200
let socket = sys::net::Socket::from_inner(fd);
198201
net::UdpSocket::from_inner(net2::UdpSocket::from_inner(socket))
199202
}

src/libstd/sys/windows/ext.rs

+18-6
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,13 @@ pub mod io {
5252
/// This function will **consume ownership** of the handle given,
5353
/// passing responsibility for closing the handle to the returned
5454
/// object.
55-
fn from_raw_handle(handle: RawHandle) -> Self;
55+
///
56+
/// This function is also unsafe as the primitives currently returned
57+
/// have the contract that they are the sole owner of the file
58+
/// descriptor they are wrapping. Usage of this function could
59+
/// accidentally allow violating this contract which can cause memory
60+
/// unsafety in code that relies on it being true.
61+
unsafe fn from_raw_handle(handle: RawHandle) -> Self;
5662
}
5763

5864
#[allow(deprecated)]
@@ -72,7 +78,7 @@ pub mod io {
7278

7379
#[unstable(feature = "from_raw_os", reason = "trait is unstable")]
7480
impl FromRawHandle for fs::File {
75-
fn from_raw_handle(handle: RawHandle) -> fs::File {
81+
unsafe fn from_raw_handle(handle: RawHandle) -> fs::File {
7682
fs::File::from_inner(sys::fs2::File::from_inner(handle))
7783
}
7884
}
@@ -124,7 +130,13 @@ pub mod io {
124130
///
125131
/// This function will **consume ownership** of the socket provided and
126132
/// it will be closed when the returned object goes out of scope.
127-
fn from_raw_socket(sock: RawSocket) -> Self;
133+
///
134+
/// This function is also unsafe as the primitives currently returned
135+
/// have the contract that they are the sole owner of the file
136+
/// descriptor they are wrapping. Usage of this function could
137+
/// accidentally allow violating this contract which can cause memory
138+
/// unsafety in code that relies on it being true.
139+
unsafe fn from_raw_socket(sock: RawSocket) -> Self;
128140
}
129141

130142
#[allow(deprecated)]
@@ -180,21 +192,21 @@ pub mod io {
180192

181193
#[unstable(feature = "from_raw_os", reason = "trait is unstable")]
182194
impl FromRawSocket for net::TcpStream {
183-
fn from_raw_socket(sock: RawSocket) -> net::TcpStream {
195+
unsafe fn from_raw_socket(sock: RawSocket) -> net::TcpStream {
184196
let sock = sys::net::Socket::from_inner(sock);
185197
net::TcpStream::from_inner(net2::TcpStream::from_inner(sock))
186198
}
187199
}
188200
#[unstable(feature = "from_raw_os", reason = "trait is unstable")]
189201
impl FromRawSocket for net::TcpListener {
190-
fn from_raw_socket(sock: RawSocket) -> net::TcpListener {
202+
unsafe fn from_raw_socket(sock: RawSocket) -> net::TcpListener {
191203
let sock = sys::net::Socket::from_inner(sock);
192204
net::TcpListener::from_inner(net2::TcpListener::from_inner(sock))
193205
}
194206
}
195207
#[unstable(feature = "from_raw_os", reason = "trait is unstable")]
196208
impl FromRawSocket for net::UdpSocket {
197-
fn from_raw_socket(sock: RawSocket) -> net::UdpSocket {
209+
unsafe fn from_raw_socket(sock: RawSocket) -> net::UdpSocket {
198210
let sock = sys::net::Socket::from_inner(sock);
199211
net::UdpSocket::from_inner(net2::UdpSocket::from_inner(sock))
200212
}

0 commit comments

Comments
 (0)