Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/net/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ mod udp;
#[cfg(not(all(target_os = "wasi", target_env = "p1")))]
pub use self::udp::UdpSocket;

#[cfg(unix)]
#[cfg(any(unix, windows))]
mod uds;
#[cfg(unix)]
pub use self::uds::{UnixDatagram, UnixListener, UnixStream};
#[cfg(windows)]
pub use self::uds::{SocketAddr, UnixListener, UnixStream};
88 changes: 87 additions & 1 deletion src/net/uds/listener.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
#[cfg(unix)]
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
#[cfg(unix)]
use std::os::unix::net::{self, SocketAddr};
#[cfg(windows)]
use std::os::windows::io::{
AsRawSocket, AsSocket, BorrowedSocket, FromRawSocket, IntoRawSocket, OwnedSocket, RawSocket,
};
use std::path::Path;
use std::{fmt, io};

use crate::io_source::IoSource;
use crate::net::UnixStream;
#[cfg(windows)]
use crate::sys::uds::{Socket, SocketAddr};
use crate::{event, sys, Interest, Registry, Token};

/// A non-blocking Unix domain socket server.
pub struct UnixListener {
#[cfg(unix)]
inner: IoSource<net::UnixListener>,
#[cfg(windows)]
inner: IoSource<Socket>,
}

impl UnixListener {
Expand All @@ -21,7 +32,19 @@ impl UnixListener {

/// Creates a new `UnixListener` bound to the specified socket `address`.
pub fn bind_addr(address: &SocketAddr) -> io::Result<UnixListener> {
sys::uds::listener::bind_addr(address).map(UnixListener::from_std)
#[cfg(unix)]
{
sys::uds::listener::bind_addr(address).map(UnixListener::from_std)
}

// Once std::os::windows::net::UnixListener is stabilized, this can be removed.
#[cfg(windows)]
{
let socket = sys::uds::listener::bind_addr(address)?;
Ok(UnixListener {
inner: IoSource::new(Socket::from(socket)),
})
}
}

/// Creates a new `UnixListener` from a standard `net::UnixListener`.
Expand All @@ -30,6 +53,7 @@ impl UnixListener {
/// standard library in the Mio equivalent. The conversion assumes nothing
/// about the underlying listener; it is left up to the user to set it in
/// non-blocking mode.
#[cfg(unix)]
pub fn from_std(listener: net::UnixListener) -> UnixListener {
UnixListener {
inner: IoSource::new(listener),
Expand Down Expand Up @@ -85,18 +109,21 @@ impl fmt::Debug for UnixListener {
}
}

#[cfg(unix)]
impl IntoRawFd for UnixListener {
fn into_raw_fd(self) -> RawFd {
self.inner.into_inner().into_raw_fd()
}
}

#[cfg(unix)]
impl AsRawFd for UnixListener {
fn as_raw_fd(&self) -> RawFd {
self.inner.as_raw_fd()
}
}

#[cfg(unix)]
impl FromRawFd for UnixListener {
/// Converts a `RawFd` to a `UnixListener`.
///
Expand All @@ -109,6 +136,7 @@ impl FromRawFd for UnixListener {
}
}

#[cfg(unix)]
impl From<UnixListener> for net::UnixListener {
fn from(listener: UnixListener) -> Self {
// Safety: This is safe since we are extracting the raw fd from a well-constructed
Expand All @@ -118,20 +146,78 @@ impl From<UnixListener> for net::UnixListener {
}
}

#[cfg(unix)]
impl From<UnixListener> for OwnedFd {
fn from(unix_listener: UnixListener) -> Self {
unix_listener.inner.into_inner().into()
}
}

#[cfg(unix)]
impl AsFd for UnixListener {
fn as_fd(&self) -> BorrowedFd<'_> {
self.inner.as_fd()
}
}

#[cfg(unix)]
impl From<OwnedFd> for UnixListener {
fn from(fd: OwnedFd) -> Self {
UnixListener::from_std(From::from(fd))
}
}

#[cfg(windows)]
impl AsRawSocket for UnixListener {
fn as_raw_socket(&self) -> RawSocket {
self.inner.as_raw_socket()
}
}

#[cfg(windows)]
impl IntoRawSocket for UnixListener {
fn into_raw_socket(self) -> RawSocket {
self.inner.into_inner().into_raw_socket()
}
}

#[cfg(windows)]
impl FromRawSocket for UnixListener {
/// # Safety
///
/// The socket must be a valid, bound, listening `AF_UNIX` socket in
/// non-blocking mode.
unsafe fn from_raw_socket(sock: RawSocket) -> UnixListener {
UnixListener {
inner: IoSource::new(unsafe { Socket::from_raw_socket(sock) }),
}
}
}

#[cfg(windows)]
impl AsSocket for UnixListener {
fn as_socket(&self) -> BorrowedSocket<'_> {
// SAFETY: the raw socket is valid for the lifetime of `self`.
unsafe { BorrowedSocket::borrow_raw(self.inner.as_raw_socket()) }
}
}

#[cfg(windows)]
impl From<UnixListener> for OwnedSocket {
fn from(listener: UnixListener) -> Self {
listener.inner.into_inner().into()
}
}

#[cfg(windows)]
impl From<OwnedSocket> for UnixListener {
/// # Notes
///
/// The caller is responsible for ensuring that the socket is in
/// non-blocking mode.
fn from(socket: OwnedSocket) -> Self {
UnixListener {
inner: IoSource::new(Socket::from(socket)),
}
}
}
6 changes: 6 additions & 0 deletions src/net/uds/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
#[cfg(unix)]
mod datagram;
#[cfg(unix)]
pub use self::datagram::UnixDatagram;

mod listener;
pub use self::listener::UnixListener;

mod stream;
pub use self::stream::UnixStream;

// This is a stand-in until std::os::windows::net::SocketAddr is stabilized.
#[cfg(windows)]

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is meant to be temporary, probably shouldn't be mio::net::uds::SocketAddr. Would want to decide on a suitable path that conveys temporariness.

pub use crate::sys::uds::SocketAddr;
Loading