Skip to main content

async_net/
unix.rs

1//! Unix domain sockets.
2//!
3//! This module is an async version of [`std::os::unix::net`].
4
5use std::fmt;
6use std::io::{self, Read as _, Write as _};
7use std::net::Shutdown;
8#[cfg(unix)]
9use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, OwnedFd, RawFd};
10use std::panic::{RefUnwindSafe, UnwindSafe};
11use std::path::Path;
12use std::pin::Pin;
13use std::sync::Arc;
14use std::task::{Context, Poll};
15
16#[doc(no_inline)]
17pub use std::os::unix::net::SocketAddr;
18
19use async_io::Async;
20use futures_lite::{prelude::*, ready};
21
22/// A Unix server, listening for connections.
23///
24/// After creating a [`UnixListener`] by [`bind`][`UnixListener::bind()`]ing it to an address, it
25/// listens for incoming connections. These can be accepted by calling
26/// [`accept()`][`UnixListener::accept()`] or by awaiting items from the async stream of
27/// [`incoming`][`UnixListener::incoming()`] connections.
28///
29/// Cloning a [`UnixListener`] creates another handle to the same socket. The socket will be closed
30/// when all handles to it are dropped.
31///
32/// # Examples
33///
34/// ```no_run
35/// use async_net::unix::UnixListener;
36/// use futures_lite::prelude::*;
37///
38/// # futures_lite::future::block_on(async {
39/// let listener = UnixListener::bind("/tmp/socket")?;
40/// let mut incoming = listener.incoming();
41///
42/// while let Some(stream) = incoming.next().await {
43///     let mut stream = stream?;
44///     stream.write_all(b"hello").await?;
45/// }
46/// # std::io::Result::Ok(()) });
47/// ```
48#[derive(Clone, Debug)]
49pub struct UnixListener {
50    inner: Arc<Async<std::os::unix::net::UnixListener>>,
51}
52
53impl UnixListener {
54    fn new(inner: Arc<Async<std::os::unix::net::UnixListener>>) -> UnixListener {
55        UnixListener { inner }
56    }
57
58    /// Creates a new [`UnixListener`] bound to the given path.
59    ///
60    /// # Examples
61    ///
62    /// ```no_run
63    /// use async_net::unix::UnixListener;
64    /// use futures_lite::prelude::*;
65    ///
66    /// # futures_lite::future::block_on(async {
67    /// let listener = UnixListener::bind("/tmp/socket")?;
68    /// let mut incoming = listener.incoming();
69    ///
70    /// while let Some(stream) = incoming.next().await {
71    ///     let mut stream = stream?;
72    ///     stream.write_all(b"hello").await?;
73    /// }
74    /// # std::io::Result::Ok(()) });
75    /// ```
76    pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixListener> {
77        let listener = Async::<std::os::unix::net::UnixListener>::bind(path)?;
78        Ok(UnixListener::new(Arc::new(listener)))
79    }
80
81    /// Accepts a new incoming connection.
82    ///
83    /// Returns a TCP stream and the address it is connected to.
84    ///
85    /// # Examples
86    ///
87    /// ```no_run
88    /// use async_net::unix::UnixListener;
89    ///
90    /// # futures_lite::future::block_on(async {
91    /// let listener = UnixListener::bind("/tmp/socket")?;
92    /// let (stream, addr) = listener.accept().await?;
93    /// # std::io::Result::Ok(()) });
94    /// ```
95    pub async fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> {
96        let (stream, addr) = self.inner.accept().await?;
97        Ok((UnixStream::new(Arc::new(stream)), addr))
98    }
99
100    /// Returns a stream of incoming connections.
101    ///
102    /// Iterating over this stream is equivalent to calling [`accept()`][`UnixListener::accept()`]
103    /// in a loop. The stream of connections is infinite, i.e awaiting the next connection will
104    /// never result in [`None`].
105    ///
106    /// # Examples
107    ///
108    /// ```no_run
109    /// use async_net::unix::UnixListener;
110    /// use futures_lite::prelude::*;
111    ///
112    /// # futures_lite::future::block_on(async {
113    /// let listener = UnixListener::bind("/tmp/socket")?;
114    /// let mut incoming = listener.incoming();
115    ///
116    /// while let Some(stream) = incoming.next().await {
117    ///     let mut stream = stream?;
118    ///     stream.write_all(b"hello").await?;
119    /// }
120    /// # std::io::Result::Ok(()) });
121    /// ```
122    pub fn incoming(&self) -> Incoming<'_> {
123        Incoming {
124            incoming: Box::pin(self.inner.incoming()),
125        }
126    }
127
128    /// Returns the local address this listener is bound to.
129    ///
130    /// # Examples
131    ///
132    /// ```no_run
133    /// use async_net::unix::UnixListener;
134    ///
135    /// # futures_lite::future::block_on(async {
136    /// let listener = UnixListener::bind("/tmp/socket")?;
137    /// println!("Local address is {:?}", listener.local_addr()?);
138    /// # std::io::Result::Ok(()) });
139    /// ```
140    pub fn local_addr(&self) -> io::Result<SocketAddr> {
141        self.inner.get_ref().local_addr()
142    }
143}
144
145impl From<Async<std::os::unix::net::UnixListener>> for UnixListener {
146    fn from(listener: Async<std::os::unix::net::UnixListener>) -> UnixListener {
147        UnixListener::new(Arc::new(listener))
148    }
149}
150
151impl TryFrom<std::os::unix::net::UnixListener> for UnixListener {
152    type Error = io::Error;
153
154    fn try_from(listener: std::os::unix::net::UnixListener) -> io::Result<UnixListener> {
155        Ok(UnixListener::new(Arc::new(Async::new(listener)?)))
156    }
157}
158
159impl From<UnixListener> for Arc<Async<std::os::unix::net::UnixListener>> {
160    fn from(val: UnixListener) -> Self {
161        val.inner
162    }
163}
164
165#[cfg(unix)]
166impl AsRawFd for UnixListener {
167    fn as_raw_fd(&self) -> RawFd {
168        self.inner.as_raw_fd()
169    }
170}
171
172#[cfg(unix)]
173impl AsFd for UnixListener {
174    fn as_fd(&self) -> BorrowedFd<'_> {
175        self.inner.get_ref().as_fd()
176    }
177}
178
179#[cfg(unix)]
180impl TryFrom<OwnedFd> for UnixListener {
181    type Error = io::Error;
182
183    fn try_from(value: OwnedFd) -> Result<Self, Self::Error> {
184        Self::try_from(std::os::unix::net::UnixListener::from(value))
185    }
186}
187
188/// A stream of incoming Unix connections.
189///
190/// This stream is infinite, i.e awaiting the next connection will never result in [`None`]. It is
191/// created by the [`UnixListener::incoming()`] method.
192pub struct Incoming<'a> {
193    incoming: Pin<
194        Box<
195            dyn Stream<Item = io::Result<Async<std::os::unix::net::UnixStream>>> + Send + Sync + 'a,
196        >,
197    >,
198}
199
200impl Stream for Incoming<'_> {
201    type Item = io::Result<UnixStream>;
202
203    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
204        let res = ready!(Pin::new(&mut self.incoming).poll_next(cx));
205        Poll::Ready(res.map(|res| res.map(|stream| UnixStream::new(Arc::new(stream)))))
206    }
207}
208
209impl fmt::Debug for Incoming<'_> {
210    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
211        write!(f, "Incoming {{ ... }}")
212    }
213}
214
215/// A Unix connection.
216///
217/// A [`UnixStream`] can be created by [`connect`][`UnixStream::connect()`]ing to an endpoint or by
218/// [`accept`][`UnixListener::accept()`]ing an incoming connection.
219///
220/// [`UnixStream`] is a bidirectional stream that implements traits [`AsyncRead`] and
221/// [`AsyncWrite`].
222///
223/// Cloning a [`UnixStream`] creates another handle to the same socket. The socket will be closed
224/// when all handles to it are dropped. The reading and writing portions of the connection can also
225/// be shut down individually with the [`shutdown()`][`UnixStream::shutdown()`] method.
226///
227/// # Examples
228///
229/// ```no_run
230/// use async_net::unix::UnixStream;
231/// use futures_lite::prelude::*;
232///
233/// # futures_lite::future::block_on(async {
234/// let mut stream = UnixStream::connect("/tmp/socket").await?;
235/// stream.write_all(b"hello").await?;
236///
237/// let mut buf = vec![0u8; 1024];
238/// let n = stream.read(&mut buf).await?;
239/// # std::io::Result::Ok(()) });
240/// ```
241pub struct UnixStream {
242    inner: Arc<Async<std::os::unix::net::UnixStream>>,
243    readable: Option<async_io::ReadableOwned<std::os::unix::net::UnixStream>>,
244    writable: Option<async_io::WritableOwned<std::os::unix::net::UnixStream>>,
245}
246
247impl UnwindSafe for UnixStream {}
248impl RefUnwindSafe for UnixStream {}
249
250impl UnixStream {
251    fn new(inner: Arc<Async<std::os::unix::net::UnixStream>>) -> UnixStream {
252        UnixStream {
253            inner,
254            readable: None,
255            writable: None,
256        }
257    }
258
259    /// Creates a Unix connection to given path.
260    ///
261    /// # Examples
262    ///
263    /// ```no_run
264    /// use async_net::unix::UnixStream;
265    ///
266    /// # futures_lite::future::block_on(async {
267    /// let stream = UnixStream::connect("/tmp/socket").await?;
268    /// # std::io::Result::Ok(()) });
269    /// ```
270    pub async fn connect<P: AsRef<Path>>(path: P) -> io::Result<UnixStream> {
271        let stream = Async::<std::os::unix::net::UnixStream>::connect(path).await?;
272        Ok(UnixStream::new(Arc::new(stream)))
273    }
274
275    /// Creates a pair of connected Unix sockets.
276    ///
277    /// # Examples
278    ///
279    /// ```no_run
280    /// use async_net::unix::UnixStream;
281    ///
282    /// # futures_lite::future::block_on(async {
283    /// let (stream1, stream2) = UnixStream::pair()?;
284    /// # std::io::Result::Ok(()) });
285    /// ```
286    pub fn pair() -> io::Result<(UnixStream, UnixStream)> {
287        let (a, b) = Async::<std::os::unix::net::UnixStream>::pair()?;
288        Ok((UnixStream::new(Arc::new(a)), UnixStream::new(Arc::new(b))))
289    }
290
291    /// Returns the local address this socket is connected to.
292    ///
293    /// # Examples
294    ///
295    /// ```no_run
296    /// use async_net::unix::UnixStream;
297    ///
298    /// # futures_lite::future::block_on(async {
299    /// let stream = UnixStream::connect("/tmp/socket").await?;
300    /// println!("Local address is {:?}", stream.local_addr()?);
301    /// # std::io::Result::Ok(()) });
302    /// ```
303    pub fn local_addr(&self) -> io::Result<SocketAddr> {
304        self.inner.get_ref().local_addr()
305    }
306
307    /// Returns the remote address this socket is connected to.
308    ///
309    /// # Examples
310    ///
311    /// ```no_run
312    /// use async_net::unix::UnixStream;
313    ///
314    /// # futures_lite::future::block_on(async {
315    /// let stream = UnixStream::connect("/tmp/socket").await?;
316    /// println!("Connected to {:?}", stream.peer_addr()?);
317    /// # std::io::Result::Ok(()) });
318    /// ```
319    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
320        self.inner.get_ref().peer_addr()
321    }
322
323    /// Shuts down the read half, write half, or both halves of this connection.
324    ///
325    /// This method will cause all pending and future I/O in the given directions to return
326    /// immediately with an appropriate value (see the documentation of [`Shutdown`]).
327    ///
328    /// ```no_run
329    /// use async_net::{Shutdown, unix::UnixStream};
330    ///
331    /// # futures_lite::future::block_on(async {
332    /// let stream = UnixStream::connect("/tmp/socket").await?;
333    /// stream.shutdown(Shutdown::Both)?;
334    /// # std::io::Result::Ok(()) });
335    /// ```
336    pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
337        self.inner.get_ref().shutdown(how)
338    }
339}
340
341impl fmt::Debug for UnixStream {
342    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
343        self.inner.fmt(f)
344    }
345}
346
347impl Clone for UnixStream {
348    fn clone(&self) -> UnixStream {
349        UnixStream::new(self.inner.clone())
350    }
351}
352
353impl From<Async<std::os::unix::net::UnixStream>> for UnixStream {
354    fn from(stream: Async<std::os::unix::net::UnixStream>) -> UnixStream {
355        UnixStream::new(Arc::new(stream))
356    }
357}
358
359impl TryFrom<std::os::unix::net::UnixStream> for UnixStream {
360    type Error = io::Error;
361
362    fn try_from(stream: std::os::unix::net::UnixStream) -> io::Result<UnixStream> {
363        Ok(UnixStream::new(Arc::new(Async::new(stream)?)))
364    }
365}
366
367impl From<UnixStream> for Arc<Async<std::os::unix::net::UnixStream>> {
368    fn from(val: UnixStream) -> Self {
369        val.inner
370    }
371}
372
373#[cfg(unix)]
374impl AsRawFd for UnixStream {
375    fn as_raw_fd(&self) -> RawFd {
376        self.inner.as_raw_fd()
377    }
378}
379
380#[cfg(unix)]
381impl AsFd for UnixStream {
382    fn as_fd(&self) -> BorrowedFd<'_> {
383        self.inner.get_ref().as_fd()
384    }
385}
386
387#[cfg(unix)]
388impl TryFrom<OwnedFd> for UnixStream {
389    type Error = io::Error;
390
391    fn try_from(value: OwnedFd) -> Result<Self, Self::Error> {
392        Self::try_from(std::os::unix::net::UnixStream::from(value))
393    }
394}
395
396impl AsyncRead for UnixStream {
397    fn poll_read(
398        mut self: Pin<&mut Self>,
399        cx: &mut Context<'_>,
400        buf: &mut [u8],
401    ) -> Poll<io::Result<usize>> {
402        loop {
403            // Attempt the non-blocking operation.
404            match self.inner.get_ref().read(buf) {
405                Err(err) if err.kind() == io::ErrorKind::WouldBlock => {}
406                res => {
407                    self.readable = None;
408                    return Poll::Ready(res);
409                }
410            }
411
412            // Initialize the future to wait for readiness.
413            if self.readable.is_none() {
414                self.readable = Some(self.inner.clone().readable_owned());
415            }
416
417            // Poll the future for readiness.
418            if let Some(f) = &mut self.readable {
419                let res = ready!(Pin::new(f).poll(cx));
420                self.readable = None;
421                res?;
422            }
423        }
424    }
425}
426
427impl AsyncWrite for UnixStream {
428    fn poll_write(
429        mut self: Pin<&mut Self>,
430        cx: &mut Context<'_>,
431        buf: &[u8],
432    ) -> Poll<io::Result<usize>> {
433        loop {
434            // Attempt the non-blocking operation.
435            match self.inner.get_ref().write(buf) {
436                Err(err) if err.kind() == io::ErrorKind::WouldBlock => {}
437                res => {
438                    self.writable = None;
439                    return Poll::Ready(res);
440                }
441            }
442
443            // Initialize the future to wait for readiness.
444            if self.writable.is_none() {
445                self.writable = Some(self.inner.clone().writable_owned());
446            }
447
448            // Poll the future for readiness.
449            if let Some(f) = &mut self.writable {
450                let res = ready!(Pin::new(f).poll(cx));
451                self.writable = None;
452                res?;
453            }
454        }
455    }
456
457    fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
458        loop {
459            // Attempt the non-blocking operation.
460            match self.inner.get_ref().flush() {
461                Err(err) if err.kind() == io::ErrorKind::WouldBlock => {}
462                res => {
463                    self.writable = None;
464                    return Poll::Ready(res);
465                }
466            }
467
468            // Initialize the future to wait for readiness.
469            if self.writable.is_none() {
470                self.writable = Some(self.inner.clone().writable_owned());
471            }
472
473            // Poll the future for readiness.
474            if let Some(f) = &mut self.writable {
475                let res = ready!(Pin::new(f).poll(cx));
476                self.writable = None;
477                res?;
478            }
479        }
480    }
481
482    fn poll_close(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
483        Poll::Ready(self.inner.get_ref().shutdown(Shutdown::Write))
484    }
485}
486
487/// A Unix datagram socket.
488///
489/// After creating a [`UnixDatagram`] by [`bind`][`UnixDatagram::bind()`]ing it to a path, data can
490/// be [sent to] and [received from] any other socket address.
491///
492/// Cloning a [`UnixDatagram`] creates another handle to the same socket. The socket will be closed
493/// when all handles to it are dropped. The reading and writing portions of the socket can also be
494/// shut down individually with the [`shutdown()`][`UnixStream::shutdown()`] method.
495///
496/// [received from]: UnixDatagram::recv_from()
497/// [sent to]: UnixDatagram::send_to()
498///
499/// # Examples
500///
501/// ```no_run
502/// use async_net::unix::UnixDatagram;
503///
504/// # futures_lite::future::block_on(async {
505/// let socket = UnixDatagram::bind("/tmp/socket1")?;
506/// socket.send_to(b"hello", "/tmp/socket2").await?;
507///
508/// let mut buf = vec![0u8; 1024];
509/// let (n, addr) = socket.recv_from(&mut buf).await?;
510/// # std::io::Result::Ok(()) });
511/// ```
512#[derive(Clone, Debug)]
513pub struct UnixDatagram {
514    inner: Arc<Async<std::os::unix::net::UnixDatagram>>,
515}
516
517impl UnixDatagram {
518    fn new(inner: Arc<Async<std::os::unix::net::UnixDatagram>>) -> UnixDatagram {
519        UnixDatagram { inner }
520    }
521
522    /// Creates a new [`UnixDatagram`] bound to the given address.
523    ///
524    /// # Examples
525    ///
526    /// ```no_run
527    /// use async_net::unix::UnixDatagram;
528    ///
529    /// # futures_lite::future::block_on(async {
530    /// let socket = UnixDatagram::bind("/tmp/socket")?;
531    /// # std::io::Result::Ok(()) });
532    /// ```
533    pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixDatagram> {
534        let socket = Async::<std::os::unix::net::UnixDatagram>::bind(path)?;
535        Ok(UnixDatagram::new(Arc::new(socket)))
536    }
537
538    /// Creates a Unix datagram socket not bound to any address.
539    ///
540    /// # Examples
541    ///
542    /// ```no_run
543    /// use async_net::unix::UnixDatagram;
544    ///
545    /// # futures_lite::future::block_on(async {
546    /// let socket = UnixDatagram::unbound()?;
547    /// # std::io::Result::Ok(()) });
548    /// ```
549    pub fn unbound() -> io::Result<UnixDatagram> {
550        let socket = Async::<std::os::unix::net::UnixDatagram>::unbound()?;
551        Ok(UnixDatagram::new(Arc::new(socket)))
552    }
553
554    /// Creates a pair of connected Unix datagram sockets.
555    ///
556    /// # Examples
557    ///
558    /// ```no_run
559    /// use async_net::unix::UnixDatagram;
560    ///
561    /// # futures_lite::future::block_on(async {
562    /// let (socket1, socket2) = UnixDatagram::pair()?;
563    /// # std::io::Result::Ok(()) });
564    /// ```
565    pub fn pair() -> io::Result<(UnixDatagram, UnixDatagram)> {
566        let (a, b) = Async::<std::os::unix::net::UnixDatagram>::pair()?;
567        Ok((
568            UnixDatagram::new(Arc::new(a)),
569            UnixDatagram::new(Arc::new(b)),
570        ))
571    }
572
573    /// Connects the Unix datagram socket to the given address.
574    ///
575    /// When connected, methods [`send()`][`UnixDatagram::send()`] and
576    /// [`recv()`][`UnixDatagram::recv()`] will use the specified address for sending and receiving
577    /// messages. Additionally, a filter will be applied to
578    /// [`recv_from()`][`UnixDatagram::recv_from()`] so that it only receives messages from that
579    /// same address.
580    ///
581    /// # Examples
582    ///
583    /// ```no_run
584    /// use async_net::unix::UnixDatagram;
585    ///
586    /// # futures_lite::future::block_on(async {
587    /// let socket = UnixDatagram::unbound()?;
588    /// socket.connect("/tmp/socket")?;
589    /// # std::io::Result::Ok(()) });
590    /// ```
591    pub fn connect<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
592        let p = path.as_ref();
593        self.inner.get_ref().connect(p)
594    }
595
596    /// Returns the local address this socket is bound to.
597    ///
598    /// # Examples
599    ///
600    /// ```no_run
601    /// use async_net::unix::UnixDatagram;
602    ///
603    /// # futures_lite::future::block_on(async {
604    /// let socket = UnixDatagram::bind("/tmp/socket")?;
605    /// println!("Bound to {:?}", socket.local_addr()?);
606    /// # std::io::Result::Ok(()) });
607    /// ```
608    pub fn local_addr(&self) -> io::Result<SocketAddr> {
609        self.inner.get_ref().local_addr()
610    }
611
612    /// Returns the remote address this socket is connected to.
613    ///
614    /// # Examples
615    ///
616    /// ```no_run
617    /// use async_net::unix::UnixDatagram;
618    ///
619    /// # futures_lite::future::block_on(async {
620    /// let socket = UnixDatagram::unbound()?;
621    /// socket.connect("/tmp/socket")?;
622    /// println!("Connected to {:?}", socket.peer_addr()?);
623    /// # std::io::Result::Ok(()) });
624    /// ```
625    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
626        self.inner.get_ref().peer_addr()
627    }
628
629    /// Receives data from an address.
630    ///
631    /// On success, returns the number of bytes received and the address data came from.
632    ///
633    /// # Examples
634    ///
635    /// ```no_run
636    /// use async_net::unix::UnixDatagram;
637    ///
638    /// # futures_lite::future::block_on(async {
639    /// let socket = UnixDatagram::bind("/tmp/socket")?;
640    ///
641    /// let mut buf = vec![0; 1024];
642    /// let (n, addr) = socket.recv_from(&mut buf).await?;
643    /// println!("Received {} bytes from {:?}", n, addr);
644    /// # std::io::Result::Ok(()) });
645    /// ```
646    pub async fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
647        self.inner.recv_from(buf).await
648    }
649
650    /// Sends data to the given address.
651    ///
652    /// On success, returns the number of bytes sent.
653    ///
654    /// # Examples
655    ///
656    /// ```no_run
657    /// use async_net::unix::UnixDatagram;
658    ///
659    /// # futures_lite::future::block_on(async {
660    /// let socket = UnixDatagram::unbound()?;
661    /// socket.send_to(b"hello", "/tmp/socket").await?;
662    /// # std::io::Result::Ok(()) });
663    /// ```
664    pub async fn send_to<P: AsRef<Path>>(&self, buf: &[u8], path: P) -> io::Result<usize> {
665        self.inner.send_to(buf, path.as_ref()).await
666    }
667
668    /// Receives data from the connected address.
669    ///
670    /// On success, returns the number of bytes received.
671    ///
672    /// # Examples
673    ///
674    /// ```no_run
675    /// use async_net::unix::UnixDatagram;
676    ///
677    /// # futures_lite::future::block_on(async {
678    /// let socket = UnixDatagram::unbound()?;
679    /// socket.connect("/tmp/socket")?;
680    ///
681    /// let mut buf = vec![0; 1024];
682    /// let n = socket.recv(&mut buf).await?;
683    /// # std::io::Result::Ok(()) });
684    /// ```
685    pub async fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
686        self.inner.recv(buf).await
687    }
688
689    /// Sends data to the connected address.
690    ///
691    /// On success, returns the number of bytes sent.
692    ///
693    /// # Examples
694    ///
695    /// ```no_run
696    /// use async_net::unix::UnixDatagram;
697    ///
698    /// # futures_lite::future::block_on(async {
699    /// let socket = UnixDatagram::unbound()?;
700    /// socket.connect("/tmp/socket")?;
701    /// socket.send(b"hello").await?;
702    /// # std::io::Result::Ok(()) });
703    /// ```
704    pub async fn send(&self, buf: &[u8]) -> io::Result<usize> {
705        self.inner.send(buf).await
706    }
707
708    /// Shuts down the read half, write half, or both halves of this socket.
709    ///
710    /// This method will cause all pending and future I/O in the given directions to return
711    /// immediately with an appropriate value (see the documentation of [`Shutdown`]).
712    ///
713    /// # Examples
714    ///
715    /// ```no_run
716    /// use async_net::{Shutdown, unix::UnixDatagram};
717    ///
718    /// # futures_lite::future::block_on(async {
719    /// let socket = UnixDatagram::unbound()?;
720    /// socket.shutdown(Shutdown::Both)?;
721    /// # std::io::Result::Ok(()) });
722    /// ```
723    pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
724        self.inner.get_ref().shutdown(how)
725    }
726}
727
728impl From<Async<std::os::unix::net::UnixDatagram>> for UnixDatagram {
729    fn from(socket: Async<std::os::unix::net::UnixDatagram>) -> UnixDatagram {
730        UnixDatagram::new(Arc::new(socket))
731    }
732}
733
734impl TryFrom<std::os::unix::net::UnixDatagram> for UnixDatagram {
735    type Error = io::Error;
736
737    fn try_from(socket: std::os::unix::net::UnixDatagram) -> io::Result<UnixDatagram> {
738        Ok(UnixDatagram::new(Arc::new(Async::new(socket)?)))
739    }
740}
741
742impl From<UnixDatagram> for Arc<Async<std::os::unix::net::UnixDatagram>> {
743    fn from(val: UnixDatagram) -> Self {
744        val.inner
745    }
746}
747
748#[cfg(unix)]
749impl AsRawFd for UnixDatagram {
750    fn as_raw_fd(&self) -> RawFd {
751        self.inner.as_raw_fd()
752    }
753}