Skip to content

Commit d8d68ac

Browse files
authored
Implement more I/O safety traits
Implement `From<OwnedFd>` and `Into<OwnedFd>` for types that implement `FromRawFd` and `IntoRawFd`. And on Windows, implement `From<OwnedSocket>`, `Into<OwnedSocket>`, and `AsSocket` for types that implement `FromRawSocket`, `IntoRawSocket`, and `AsRawSocket`.
1 parent 8b6c4b5 commit d8d68ac

File tree

7 files changed

+224
-13
lines changed

7 files changed

+224
-13
lines changed

src/net/tcp/listener.rs

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
use std::net::{self, SocketAddr};
22
#[cfg(any(unix, target_os = "wasi"))]
3-
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd};
3+
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
44
// TODO: once <https://github.com/rust-lang/rust/issues/126198> is fixed this
55
// can use `std::os::fd` and be merged with the above.
66
#[cfg(target_os = "hermit")]
7-
use std::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd};
7+
use std::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
88
#[cfg(windows)]
9-
use std::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket};
9+
use std::os::windows::io::{
10+
AsRawSocket, AsSocket, BorrowedSocket, FromRawSocket, IntoRawSocket, OwnedSocket, RawSocket,
11+
};
1012
use std::{fmt, io};
1113

1214
use crate::io_source::IoSource;
@@ -195,13 +197,33 @@ impl FromRawFd for TcpListener {
195197
}
196198
}
197199

200+
#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
201+
impl From<TcpListener> for OwnedFd {
202+
fn from(tcp_listener: TcpListener) -> Self {
203+
tcp_listener.inner.into_inner().into()
204+
}
205+
}
206+
198207
#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
199208
impl AsFd for TcpListener {
200209
fn as_fd(&self) -> BorrowedFd<'_> {
201210
self.inner.as_fd()
202211
}
203212
}
204213

214+
#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
215+
impl From<OwnedFd> for TcpListener {
216+
/// Converts a `RawFd` to a `TcpListener`.
217+
///
218+
/// # Notes
219+
///
220+
/// The caller is responsible for ensuring that the socket is in
221+
/// non-blocking mode.
222+
fn from(fd: OwnedFd) -> Self {
223+
TcpListener::from_std(From::from(fd))
224+
}
225+
}
226+
205227
#[cfg(windows)]
206228
impl IntoRawSocket for TcpListener {
207229
fn into_raw_socket(self) -> RawSocket {
@@ -229,6 +251,33 @@ impl FromRawSocket for TcpListener {
229251
}
230252
}
231253

254+
#[cfg(windows)]
255+
impl From<TcpListener> for OwnedSocket {
256+
fn from(tcp_listener: TcpListener) -> Self {
257+
tcp_listener.inner.into_inner().into()
258+
}
259+
}
260+
261+
#[cfg(windows)]
262+
impl AsSocket for TcpListener {
263+
fn as_socket(&self) -> BorrowedSocket<'_> {
264+
self.inner.as_socket()
265+
}
266+
}
267+
268+
#[cfg(windows)]
269+
impl From<OwnedSocket> for TcpListener {
270+
/// Converts a `RawSocket` to a `TcpListener`.
271+
///
272+
/// # Notes
273+
///
274+
/// The caller is responsible for ensuring that the socket is in
275+
/// non-blocking mode.
276+
fn from(socket: OwnedSocket) -> Self {
277+
TcpListener::from_std(From::from(socket))
278+
}
279+
}
280+
232281
impl From<TcpListener> for net::TcpListener {
233282
fn from(listener: TcpListener) -> Self {
234283
// Safety: This is safe since we are extracting the raw fd from a well-constructed

src/net/tcp/stream.rs

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ use std::fmt;
22
use std::io::{self, IoSlice, IoSliceMut, Read, Write};
33
use std::net::{self, Shutdown, SocketAddr};
44
#[cfg(any(unix, target_os = "wasi"))]
5-
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd};
5+
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
66
// TODO: once <https://github.com/rust-lang/rust/issues/126198> is fixed this
77
// can use `std::os::fd` and be merged with the above.
88
#[cfg(target_os = "hermit")]
9-
use std::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd};
9+
use std::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
1010
#[cfg(windows)]
11-
use std::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket};
11+
use std::os::windows::io::{
12+
AsRawSocket, AsSocket, BorrowedSocket, FromRawSocket, IntoRawSocket, OwnedSocket, RawSocket,
13+
};
1214

1315
use crate::io_source::IoSource;
1416
#[cfg(not(target_os = "wasi"))]
@@ -377,13 +379,33 @@ impl FromRawFd for TcpStream {
377379
}
378380
}
379381

382+
#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
383+
impl From<TcpStream> for OwnedFd {
384+
fn from(tcp_stream: TcpStream) -> Self {
385+
tcp_stream.inner.into_inner().into()
386+
}
387+
}
388+
380389
#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
381390
impl AsFd for TcpStream {
382391
fn as_fd(&self) -> BorrowedFd<'_> {
383392
self.inner.as_fd()
384393
}
385394
}
386395

396+
#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
397+
impl From<OwnedFd> for TcpStream {
398+
/// Converts a `RawFd` to a `TcpStream`.
399+
///
400+
/// # Notes
401+
///
402+
/// The caller is responsible for ensuring that the socket is in
403+
/// non-blocking mode.
404+
fn from(fd: OwnedFd) -> Self {
405+
TcpStream::from_std(From::from(fd))
406+
}
407+
}
408+
387409
#[cfg(windows)]
388410
impl IntoRawSocket for TcpStream {
389411
fn into_raw_socket(self) -> RawSocket {
@@ -411,6 +433,33 @@ impl FromRawSocket for TcpStream {
411433
}
412434
}
413435

436+
#[cfg(windows)]
437+
impl From<TcpStream> for OwnedSocket {
438+
fn from(tcp_stream: TcpStream) -> Self {
439+
tcp_stream.inner.into_inner().into()
440+
}
441+
}
442+
443+
#[cfg(windows)]
444+
impl AsSocket for TcpStream {
445+
fn as_socket(&self) -> BorrowedSocket<'_> {
446+
self.inner.as_socket()
447+
}
448+
}
449+
450+
#[cfg(windows)]
451+
impl From<OwnedSocket> for TcpStream {
452+
/// Converts a `RawSocket` to a `TcpStream`.
453+
///
454+
/// # Notes
455+
///
456+
/// The caller is responsible for ensuring that the socket is in
457+
/// non-blocking mode.
458+
fn from(socket: OwnedSocket) -> Self {
459+
TcpStream::from_std(From::from(socket))
460+
}
461+
}
462+
414463
impl From<TcpStream> for net::TcpStream {
415464
fn from(stream: TcpStream) -> Self {
416465
// Safety: This is safe since we are extracting the raw fd from a well-constructed

src/net/udp.rs

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@
99
1010
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr};
1111
#[cfg(any(unix, target_os = "wasi"))]
12-
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd};
12+
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
1313
// TODO: once <https://github.com/rust-lang/rust/issues/126198> is fixed this
1414
// can use `std::os::fd` and be merged with the above.
1515
#[cfg(target_os = "hermit")]
16-
use std::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd};
16+
use std::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
1717
#[cfg(windows)]
18-
use std::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket};
18+
use std::os::windows::io::{
19+
AsRawSocket, AsSocket, BorrowedSocket, FromRawSocket, IntoRawSocket, OwnedSocket, RawSocket,
20+
};
1921
use std::{fmt, io, net};
2022

2123
use crate::io_source::IoSource;
@@ -671,13 +673,33 @@ impl FromRawFd for UdpSocket {
671673
}
672674
}
673675

676+
#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
677+
impl From<UdpSocket> for OwnedFd {
678+
fn from(udp_socket: UdpSocket) -> Self {
679+
udp_socket.inner.into_inner().into()
680+
}
681+
}
682+
674683
#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
675684
impl AsFd for UdpSocket {
676685
fn as_fd(&self) -> BorrowedFd<'_> {
677686
self.inner.as_fd()
678687
}
679688
}
680689

690+
#[cfg(any(unix, target_os = "hermit", target_os = "wasi"))]
691+
impl From<OwnedFd> for UdpSocket {
692+
/// Converts a `RawFd` to a `UdpSocket`.
693+
///
694+
/// # Notes
695+
///
696+
/// The caller is responsible for ensuring that the socket is in
697+
/// non-blocking mode.
698+
fn from(fd: OwnedFd) -> Self {
699+
UdpSocket::from_std(From::from(fd))
700+
}
701+
}
702+
681703
#[cfg(windows)]
682704
impl IntoRawSocket for UdpSocket {
683705
fn into_raw_socket(self) -> RawSocket {
@@ -705,6 +727,33 @@ impl FromRawSocket for UdpSocket {
705727
}
706728
}
707729

730+
#[cfg(windows)]
731+
impl From<UdpSocket> for OwnedSocket {
732+
fn from(udp_socket: UdpSocket) -> Self {
733+
udp_socket.inner.into_inner().into()
734+
}
735+
}
736+
737+
#[cfg(windows)]
738+
impl AsSocket for UdpSocket {
739+
fn as_socket(&self) -> BorrowedSocket<'_> {
740+
self.inner.as_socket()
741+
}
742+
}
743+
744+
#[cfg(windows)]
745+
impl From<OwnedSocket> for UdpSocket {
746+
/// Converts a `RawSocket` to a `UdpSocket`.
747+
///
748+
/// # Notes
749+
///
750+
/// The caller is responsible for ensuring that the socket is in
751+
/// non-blocking mode.
752+
fn from(socket: OwnedSocket) -> Self {
753+
UdpSocket::from_std(From::from(socket))
754+
}
755+
}
756+
708757
impl From<UdpSocket> for net::UdpSocket {
709758
fn from(socket: UdpSocket) -> Self {
710759
// Safety: This is safe since we are extracting the raw fd from a well-constructed

src/net/uds/datagram.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use std::net::Shutdown;
2-
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd};
2+
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
33
use std::os::unix::net::{self, SocketAddr};
44
use std::path::Path;
55
use std::{fmt, io};
@@ -249,8 +249,20 @@ impl From<UnixDatagram> for net::UnixDatagram {
249249
}
250250
}
251251

252+
impl From<UnixDatagram> for OwnedFd {
253+
fn from(unix_datagram: UnixDatagram) -> Self {
254+
unix_datagram.inner.into_inner().into()
255+
}
256+
}
257+
252258
impl AsFd for UnixDatagram {
253259
fn as_fd(&self) -> BorrowedFd<'_> {
254260
self.inner.as_fd()
255261
}
256262
}
263+
264+
impl From<OwnedFd> for UnixDatagram {
265+
fn from(fd: OwnedFd) -> Self {
266+
UnixDatagram::from_std(From::from(fd))
267+
}
268+
}

src/net/uds/listener.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd};
1+
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
22
use std::os::unix::net::{self, SocketAddr};
33
use std::path::Path;
44
use std::{fmt, io};
@@ -118,8 +118,20 @@ impl From<UnixListener> for net::UnixListener {
118118
}
119119
}
120120

121+
impl From<UnixListener> for OwnedFd {
122+
fn from(unix_listener: UnixListener) -> Self {
123+
unix_listener.inner.into_inner().into()
124+
}
125+
}
126+
121127
impl AsFd for UnixListener {
122128
fn as_fd(&self) -> BorrowedFd<'_> {
123129
self.inner.as_fd()
124130
}
125131
}
132+
133+
impl From<OwnedFd> for UnixListener {
134+
fn from(fd: OwnedFd) -> Self {
135+
UnixListener::from_std(From::from(fd))
136+
}
137+
}

src/net/uds/stream.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::fmt;
22
use std::io::{self, IoSlice, IoSliceMut, Read, Write};
33
use std::net::Shutdown;
4-
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd};
4+
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
55
use std::os::unix::net::{self, SocketAddr};
66
use std::path::Path;
77

@@ -262,8 +262,20 @@ impl From<UnixStream> for net::UnixStream {
262262
}
263263
}
264264

265+
impl From<UnixStream> for OwnedFd {
266+
fn from(unix_stream: UnixStream) -> Self {
267+
unix_stream.inner.into_inner().into()
268+
}
269+
}
270+
265271
impl AsFd for UnixStream {
266272
fn as_fd(&self) -> BorrowedFd<'_> {
267273
self.inner.as_fd()
268274
}
269275
}
276+
277+
impl From<OwnedFd> for UnixStream {
278+
fn from(fd: OwnedFd) -> Self {
279+
UnixStream::from_std(From::from(fd))
280+
}
281+
}

0 commit comments

Comments
 (0)