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