Skip to content

Commit d4e8003

Browse files
committed
Add Socket::pair
1 parent f6bc015 commit d4e8003

File tree

3 files changed

+29
-0
lines changed

3 files changed

+29
-0
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,4 @@ libc = "0.2.14"
2323

2424
[features]
2525
reuseport = []
26+
pair = []

src/socket.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,19 @@ impl Socket {
3636
})
3737
}
3838

39+
/// Creates a pair of sockets which are connected to each other.
40+
///
41+
/// This function corresponds to `socketpair(2)`.
42+
///
43+
/// This function is only available on Unix when the `pair` feature is
44+
/// enabled.
45+
#[cfg(all(unix, feature = "pair"))]
46+
pub fn pair(domain: Domain, type_: Type, protocol: Option<Protocol>) -> io::Result<(Socket, Socket)> {
47+
let protocol = protocol.map(|p| p.0).unwrap_or(0);
48+
let sockets = sys::Socket::pair(domain.0, type_.0, protocol)?;
49+
Ok((Socket { inner: sockets.0 }, Socket { inner: sockets.1 }))
50+
}
51+
3952
/// Consumes this `Socket`, converting it to a `TcpStream`.
4053
pub fn into_tcp_stream(self) -> net::TcpStream {
4154
self.into()

src/sys/unix/mod.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,21 @@ impl Socket {
9494
}
9595
}
9696

97+
pub fn pair(family: c_int, ty: c_int, protocol: c_int) -> io::Result<(Socket, Socket)> {
98+
unsafe {
99+
let mut fds = [0, 0];
100+
cvt(libc::socketpair(family, ty, protocol, fds.as_mut_ptr()))?;
101+
let fds = (Socket::from_raw_fd(fds[0]), Socket::from_raw_fd(fds[1]));
102+
set_cloexec(fds.0.as_raw_fd())?;
103+
set_cloexec(fds.1.as_raw_fd())?;
104+
#[cfg(target_os = "macos")] {
105+
fds.0.setsockopt(libc::SOL_SOCKET, libc::SO_NOSIGPIPE, 1i32)?;
106+
fds.1.setsockopt(libc::SOL_SOCKET, libc::SO_NOSIGPIPE, 1i32)?;
107+
}
108+
Ok(fds)
109+
}
110+
}
111+
97112
pub fn bind(&self, addr: &SockAddr) -> io::Result<()> {
98113
unsafe {
99114
cvt(libc::bind(self.fd, addr.as_ptr(), addr.len() as _)).map(|_| ())

0 commit comments

Comments
 (0)