use std::{io, net::Shutdown, path::Path};
use socket2::{Domain, SockAddr, Type};
#[cfg(feature = "runtime")]
use crate::{
buf::{IoBuf, IoBufMut, VectoredBufWrapper},
BufResult,
};
use crate::{
impl_raw_fd,
net::{Socket, ToSockAddrs},
};
pub struct UnixListener {
inner: Socket,
}
impl UnixListener {
pub fn bind(path: impl AsRef<Path>) -> io::Result<Self> {
Self::bind_addr(SockAddr::unix(path)?)
}
pub fn bind_addr(addr: impl ToSockAddrs) -> io::Result<Self> {
super::each_addr(addr, |addr| {
let socket = Socket::bind(&addr, Type::STREAM, None)?;
socket.listen(1024)?;
Ok(UnixListener { inner: socket })
})
}
pub fn try_clone(&self) -> io::Result<Self> {
Ok(Self {
inner: self.inner.try_clone()?,
})
}
#[cfg(feature = "runtime")]
pub async fn accept(&self) -> io::Result<(UnixStream, SockAddr)> {
let (socket, addr) = self.inner.accept().await?;
let stream = UnixStream { inner: socket };
Ok((stream, addr))
}
pub fn local_addr(&self) -> io::Result<SockAddr> {
self.inner.local_addr()
}
}
impl_raw_fd!(UnixListener, inner);
pub struct UnixStream {
inner: Socket,
}
impl UnixStream {
pub fn connect(path: impl AsRef<Path>) -> io::Result<Self> {
Self::connect_addr(SockAddr::unix(path)?)
}
pub fn connect_addr(addr: impl ToSockAddrs) -> io::Result<Self> {
super::each_addr(addr, |addr| {
let socket = Socket::new(Domain::UNIX, Type::STREAM, None)?;
socket.connect(&addr)?;
let unix_stream = UnixStream { inner: socket };
Ok(unix_stream)
})
}
pub fn try_clone(&self) -> io::Result<Self> {
Ok(Self {
inner: self.inner.try_clone()?,
})
}
pub fn peer_addr(&self) -> io::Result<SockAddr> {
self.inner.peer_addr()
}
pub fn local_addr(&self) -> io::Result<SockAddr> {
self.inner.local_addr()
}
pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
self.inner.shutdown(how)
}
#[cfg(feature = "runtime")]
pub async fn recv<T: IoBufMut<'static>>(&self, buffer: T) -> BufResult<usize, T> {
self.inner.recv(buffer).await
}
#[cfg(feature = "runtime")]
pub async fn recv_exact<T: IoBufMut<'static>>(&self, buffer: T) -> BufResult<usize, T> {
self.inner.recv_exact(buffer).await
}
#[cfg(feature = "runtime")]
pub async fn recv_vectored<T: IoBufMut<'static>>(
&self,
buffer: VectoredBufWrapper<'static, T>,
) -> BufResult<usize, VectoredBufWrapper<'static, T>> {
self.inner.recv_vectored(buffer).await
}
#[cfg(feature = "runtime")]
pub async fn send<T: IoBuf<'static>>(&self, buffer: T) -> BufResult<usize, T> {
self.inner.send(buffer).await
}
#[cfg(feature = "runtime")]
pub async fn send_all<T: IoBuf<'static>>(&self, buffer: T) -> BufResult<usize, T> {
self.inner.send_all(buffer).await
}
#[cfg(feature = "runtime")]
pub async fn send_vectored<T: IoBuf<'static>>(
&self,
buffer: VectoredBufWrapper<'static, T>,
) -> BufResult<usize, VectoredBufWrapper<'static, T>> {
self.inner.send_vectored(buffer).await
}
}
impl_raw_fd!(UnixStream, inner);