std/os/unix/net/stream.rs
1cfg_if::cfg_if! {
2 if #[cfg(any(
3 target_os = "linux", target_os = "android",
4 target_os = "hurd",
5 target_os = "dragonfly", target_os = "freebsd",
6 target_os = "openbsd", target_os = "netbsd",
7 target_os = "solaris", target_os = "illumos",
8 target_os = "haiku", target_os = "nto",
9 target_os = "cygwin"))] {
10 use libc::MSG_NOSIGNAL;
11 } else {
12 const MSG_NOSIGNAL: core::ffi::c_int = 0x0;
13 }
14}
15
16use super::{SocketAddr, sockaddr_un};
17#[cfg(any(doc, target_os = "android", target_os = "linux"))]
18use super::{SocketAncillary, recv_vectored_with_ancillary_from, send_vectored_with_ancillary_to};
19#[cfg(any(
20 target_os = "android",
21 target_os = "linux",
22 target_os = "dragonfly",
23 target_os = "freebsd",
24 target_os = "netbsd",
25 target_os = "openbsd",
26 target_os = "nto",
27 target_vendor = "apple",
28 target_os = "cygwin"
29))]
30use super::{UCred, peer_cred};
31use crate::fmt;
32use crate::io::{self, IoSlice, IoSliceMut};
33use crate::net::Shutdown;
34use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
35use crate::path::Path;
36use crate::sealed::Sealed;
37use crate::sys::cvt;
38use crate::sys::net::Socket;
39use crate::sys_common::{AsInner, FromInner};
40use crate::time::Duration;
41
42/// A Unix stream socket.
43///
44/// # Examples
45///
46/// ```no_run
47/// use std::os::unix::net::UnixStream;
48/// use std::io::prelude::*;
49///
50/// fn main() -> std::io::Result<()> {
51/// let mut stream = UnixStream::connect("/path/to/my/socket")?;
52/// stream.write_all(b"hello world")?;
53/// let mut response = String::new();
54/// stream.read_to_string(&mut response)?;
55/// println!("{response}");
56/// Ok(())
57/// }
58/// ```
59///
60/// # `SIGPIPE`
61///
62/// Writes to the underlying socket in `SOCK_STREAM` mode are made with `MSG_NOSIGNAL` flag.
63/// This suppresses the emission of the `SIGPIPE` signal when writing to disconnected socket.
64/// In some cases getting a `SIGPIPE` would trigger process termination.
65#[stable(feature = "unix_socket", since = "1.10.0")]
66pub struct UnixStream(pub(super) Socket);
67
68/// Allows extension traits within `std`.
69#[unstable(feature = "sealed", issue = "none")]
70impl Sealed for UnixStream {}
71
72#[stable(feature = "unix_socket", since = "1.10.0")]
73impl fmt::Debug for UnixStream {
74 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
75 let mut builder = fmt.debug_struct("UnixStream");
76 builder.field("fd", self.0.as_inner());
77 if let Ok(addr) = self.local_addr() {
78 builder.field("local", &addr);
79 }
80 if let Ok(addr) = self.peer_addr() {
81 builder.field("peer", &addr);
82 }
83 builder.finish()
84 }
85}
86
87impl UnixStream {
88 /// Connects to the socket named by `path`.
89 ///
90 /// # Examples
91 ///
92 /// ```no_run
93 /// use std::os::unix::net::UnixStream;
94 ///
95 /// let socket = match UnixStream::connect("/tmp/sock") {
96 /// Ok(sock) => sock,
97 /// Err(e) => {
98 /// println!("Couldn't connect: {e:?}");
99 /// return
100 /// }
101 /// };
102 /// ```
103 #[stable(feature = "unix_socket", since = "1.10.0")]
104 pub fn connect<P: AsRef<Path>>(path: P) -> io::Result<UnixStream> {
105 unsafe {
106 let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
107 let (addr, len) = sockaddr_un(path.as_ref())?;
108
109 cvt(libc::connect(inner.as_raw_fd(), (&raw const addr) as *const _, len))?;
110 Ok(UnixStream(inner))
111 }
112 }
113
114 /// Connects to the socket specified by [`address`].
115 ///
116 /// [`address`]: crate::os::unix::net::SocketAddr
117 ///
118 /// # Examples
119 ///
120 /// ```no_run
121 /// use std::os::unix::net::{UnixListener, UnixStream};
122 ///
123 /// fn main() -> std::io::Result<()> {
124 /// let listener = UnixListener::bind("/path/to/the/socket")?;
125 /// let addr = listener.local_addr()?;
126 ///
127 /// let sock = match UnixStream::connect_addr(&addr) {
128 /// Ok(sock) => sock,
129 /// Err(e) => {
130 /// println!("Couldn't connect: {e:?}");
131 /// return Err(e)
132 /// }
133 /// };
134 /// Ok(())
135 /// }
136 /// ````
137 #[stable(feature = "unix_socket_abstract", since = "1.70.0")]
138 pub fn connect_addr(socket_addr: &SocketAddr) -> io::Result<UnixStream> {
139 unsafe {
140 let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
141 cvt(libc::connect(
142 inner.as_raw_fd(),
143 (&raw const socket_addr.addr) as *const _,
144 socket_addr.len,
145 ))?;
146 Ok(UnixStream(inner))
147 }
148 }
149
150 /// Creates an unnamed pair of connected sockets.
151 ///
152 /// Returns two `UnixStream`s which are connected to each other.
153 ///
154 /// # Examples
155 ///
156 /// ```no_run
157 /// use std::os::unix::net::UnixStream;
158 ///
159 /// let (sock1, sock2) = match UnixStream::pair() {
160 /// Ok((sock1, sock2)) => (sock1, sock2),
161 /// Err(e) => {
162 /// println!("Couldn't create a pair of sockets: {e:?}");
163 /// return
164 /// }
165 /// };
166 /// ```
167 #[stable(feature = "unix_socket", since = "1.10.0")]
168 pub fn pair() -> io::Result<(UnixStream, UnixStream)> {
169 let (i1, i2) = Socket::new_pair(libc::AF_UNIX, libc::SOCK_STREAM)?;
170 Ok((UnixStream(i1), UnixStream(i2)))
171 }
172
173 /// Creates a new independently owned handle to the underlying socket.
174 ///
175 /// The returned `UnixStream` is a reference to the same stream that this
176 /// object references. Both handles will read and write the same stream of
177 /// data, and options set on one stream will be propagated to the other
178 /// stream.
179 ///
180 /// # Examples
181 ///
182 /// ```no_run
183 /// use std::os::unix::net::UnixStream;
184 ///
185 /// fn main() -> std::io::Result<()> {
186 /// let socket = UnixStream::connect("/tmp/sock")?;
187 /// let sock_copy = socket.try_clone().expect("Couldn't clone socket");
188 /// Ok(())
189 /// }
190 /// ```
191 #[stable(feature = "unix_socket", since = "1.10.0")]
192 pub fn try_clone(&self) -> io::Result<UnixStream> {
193 self.0.duplicate().map(UnixStream)
194 }
195
196 /// Returns the socket address of the local half of this connection.
197 ///
198 /// # Examples
199 ///
200 /// ```no_run
201 /// use std::os::unix::net::UnixStream;
202 ///
203 /// fn main() -> std::io::Result<()> {
204 /// let socket = UnixStream::connect("/tmp/sock")?;
205 /// let addr = socket.local_addr().expect("Couldn't get local address");
206 /// Ok(())
207 /// }
208 /// ```
209 #[stable(feature = "unix_socket", since = "1.10.0")]
210 pub fn local_addr(&self) -> io::Result<SocketAddr> {
211 SocketAddr::new(|addr, len| unsafe { libc::getsockname(self.as_raw_fd(), addr, len) })
212 }
213
214 /// Returns the socket address of the remote half of this connection.
215 ///
216 /// # Examples
217 ///
218 /// ```no_run
219 /// use std::os::unix::net::UnixStream;
220 ///
221 /// fn main() -> std::io::Result<()> {
222 /// let socket = UnixStream::connect("/tmp/sock")?;
223 /// let addr = socket.peer_addr().expect("Couldn't get peer address");
224 /// Ok(())
225 /// }
226 /// ```
227 #[stable(feature = "unix_socket", since = "1.10.0")]
228 pub fn peer_addr(&self) -> io::Result<SocketAddr> {
229 SocketAddr::new(|addr, len| unsafe { libc::getpeername(self.as_raw_fd(), addr, len) })
230 }
231
232 /// Gets the peer credentials for this Unix domain socket.
233 ///
234 /// # Examples
235 ///
236 /// ```no_run
237 /// #![feature(peer_credentials_unix_socket)]
238 /// use std::os::unix::net::UnixStream;
239 ///
240 /// fn main() -> std::io::Result<()> {
241 /// let socket = UnixStream::connect("/tmp/sock")?;
242 /// let peer_cred = socket.peer_cred().expect("Couldn't get peer credentials");
243 /// Ok(())
244 /// }
245 /// ```
246 #[unstable(feature = "peer_credentials_unix_socket", issue = "42839", reason = "unstable")]
247 #[cfg(any(
248 target_os = "android",
249 target_os = "linux",
250 target_os = "dragonfly",
251 target_os = "freebsd",
252 target_os = "netbsd",
253 target_os = "openbsd",
254 target_os = "nto",
255 target_vendor = "apple",
256 target_os = "cygwin"
257 ))]
258 pub fn peer_cred(&self) -> io::Result<UCred> {
259 peer_cred(self)
260 }
261
262 /// Sets the read timeout for the socket.
263 ///
264 /// If the provided value is [`None`], then [`read`] calls will block
265 /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this
266 /// method.
267 ///
268 /// [`read`]: io::Read::read
269 ///
270 /// # Examples
271 ///
272 /// ```no_run
273 /// use std::os::unix::net::UnixStream;
274 /// use std::time::Duration;
275 ///
276 /// fn main() -> std::io::Result<()> {
277 /// let socket = UnixStream::connect("/tmp/sock")?;
278 /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
279 /// Ok(())
280 /// }
281 /// ```
282 ///
283 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
284 /// method:
285 ///
286 /// ```no_run
287 /// use std::io;
288 /// use std::os::unix::net::UnixStream;
289 /// use std::time::Duration;
290 ///
291 /// fn main() -> std::io::Result<()> {
292 /// let socket = UnixStream::connect("/tmp/sock")?;
293 /// let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
294 /// let err = result.unwrap_err();
295 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
296 /// Ok(())
297 /// }
298 /// ```
299 #[stable(feature = "unix_socket", since = "1.10.0")]
300 pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
301 self.0.set_timeout(timeout, libc::SO_RCVTIMEO)
302 }
303
304 /// Sets the write timeout for the socket.
305 ///
306 /// If the provided value is [`None`], then [`write`] calls will block
307 /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is
308 /// passed to this method.
309 ///
310 /// [`read`]: io::Read::read
311 ///
312 /// # Examples
313 ///
314 /// ```no_run
315 /// use std::os::unix::net::UnixStream;
316 /// use std::time::Duration;
317 ///
318 /// fn main() -> std::io::Result<()> {
319 /// let socket = UnixStream::connect("/tmp/sock")?;
320 /// socket.set_write_timeout(Some(Duration::new(1, 0)))
321 /// .expect("Couldn't set write timeout");
322 /// Ok(())
323 /// }
324 /// ```
325 ///
326 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
327 /// method:
328 ///
329 /// ```no_run
330 /// use std::io;
331 /// use std::os::unix::net::UnixStream;
332 /// use std::time::Duration;
333 ///
334 /// fn main() -> std::io::Result<()> {
335 /// let socket = UnixStream::connect("/tmp/sock")?;
336 /// let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
337 /// let err = result.unwrap_err();
338 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
339 /// Ok(())
340 /// }
341 /// ```
342 #[stable(feature = "unix_socket", since = "1.10.0")]
343 pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
344 self.0.set_timeout(timeout, libc::SO_SNDTIMEO)
345 }
346
347 /// Returns the read timeout of this socket.
348 ///
349 /// # Examples
350 ///
351 /// ```no_run
352 /// use std::os::unix::net::UnixStream;
353 /// use std::time::Duration;
354 ///
355 /// fn main() -> std::io::Result<()> {
356 /// let socket = UnixStream::connect("/tmp/sock")?;
357 /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
358 /// assert_eq!(socket.read_timeout()?, Some(Duration::new(1, 0)));
359 /// Ok(())
360 /// }
361 /// ```
362 #[stable(feature = "unix_socket", since = "1.10.0")]
363 pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
364 self.0.timeout(libc::SO_RCVTIMEO)
365 }
366
367 /// Returns the write timeout of this socket.
368 ///
369 /// # Examples
370 ///
371 /// ```no_run
372 /// use std::os::unix::net::UnixStream;
373 /// use std::time::Duration;
374 ///
375 /// fn main() -> std::io::Result<()> {
376 /// let socket = UnixStream::connect("/tmp/sock")?;
377 /// socket.set_write_timeout(Some(Duration::new(1, 0)))
378 /// .expect("Couldn't set write timeout");
379 /// assert_eq!(socket.write_timeout()?, Some(Duration::new(1, 0)));
380 /// Ok(())
381 /// }
382 /// ```
383 #[stable(feature = "unix_socket", since = "1.10.0")]
384 pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
385 self.0.timeout(libc::SO_SNDTIMEO)
386 }
387
388 /// Moves the socket into or out of nonblocking mode.
389 ///
390 /// # Examples
391 ///
392 /// ```no_run
393 /// use std::os::unix::net::UnixStream;
394 ///
395 /// fn main() -> std::io::Result<()> {
396 /// let socket = UnixStream::connect("/tmp/sock")?;
397 /// socket.set_nonblocking(true).expect("Couldn't set nonblocking");
398 /// Ok(())
399 /// }
400 /// ```
401 #[stable(feature = "unix_socket", since = "1.10.0")]
402 pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
403 self.0.set_nonblocking(nonblocking)
404 }
405
406 /// Set the id of the socket for network filtering purpose
407 ///
408 #[cfg_attr(
409 any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"),
410 doc = "```no_run"
411 )]
412 #[cfg_attr(
413 not(any(target_os = "linux", target_os = "freebsd", target_os = "openbsd")),
414 doc = "```ignore"
415 )]
416 /// #![feature(unix_set_mark)]
417 /// use std::os::unix::net::UnixStream;
418 ///
419 /// fn main() -> std::io::Result<()> {
420 /// let sock = UnixStream::connect("/tmp/sock")?;
421 /// sock.set_mark(32)?;
422 /// Ok(())
423 /// }
424 /// ```
425 #[cfg(any(doc, target_os = "linux", target_os = "freebsd", target_os = "openbsd",))]
426 #[unstable(feature = "unix_set_mark", issue = "96467")]
427 pub fn set_mark(&self, mark: u32) -> io::Result<()> {
428 self.0.set_mark(mark)
429 }
430
431 /// Returns the value of the `SO_ERROR` option.
432 ///
433 /// # Examples
434 ///
435 /// ```no_run
436 /// use std::os::unix::net::UnixStream;
437 ///
438 /// fn main() -> std::io::Result<()> {
439 /// let socket = UnixStream::connect("/tmp/sock")?;
440 /// if let Ok(Some(err)) = socket.take_error() {
441 /// println!("Got error: {err:?}");
442 /// }
443 /// Ok(())
444 /// }
445 /// ```
446 ///
447 /// # Platform specific
448 /// On Redox this always returns `None`.
449 #[stable(feature = "unix_socket", since = "1.10.0")]
450 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
451 self.0.take_error()
452 }
453
454 /// Shuts down the read, write, or both halves of this connection.
455 ///
456 /// This function will cause all pending and future I/O calls on the
457 /// specified portions to immediately return with an appropriate value
458 /// (see the documentation of [`Shutdown`]).
459 ///
460 /// # Examples
461 ///
462 /// ```no_run
463 /// use std::os::unix::net::UnixStream;
464 /// use std::net::Shutdown;
465 ///
466 /// fn main() -> std::io::Result<()> {
467 /// let socket = UnixStream::connect("/tmp/sock")?;
468 /// socket.shutdown(Shutdown::Both).expect("shutdown function failed");
469 /// Ok(())
470 /// }
471 /// ```
472 #[stable(feature = "unix_socket", since = "1.10.0")]
473 pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
474 self.0.shutdown(how)
475 }
476
477 /// Receives data on the socket from the remote address to which it is
478 /// connected, without removing that data from the queue. On success,
479 /// returns the number of bytes peeked.
480 ///
481 /// Successive calls return the same data. This is accomplished by passing
482 /// `MSG_PEEK` as a flag to the underlying `recv` system call.
483 ///
484 /// # Examples
485 ///
486 /// ```no_run
487 /// #![feature(unix_socket_peek)]
488 ///
489 /// use std::os::unix::net::UnixStream;
490 ///
491 /// fn main() -> std::io::Result<()> {
492 /// let socket = UnixStream::connect("/tmp/sock")?;
493 /// let mut buf = [0; 10];
494 /// let len = socket.peek(&mut buf).expect("peek failed");
495 /// Ok(())
496 /// }
497 /// ```
498 #[unstable(feature = "unix_socket_peek", issue = "76923")]
499 pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
500 self.0.peek(buf)
501 }
502
503 /// Receives data and ancillary data from socket.
504 ///
505 /// On success, returns the number of bytes read.
506 ///
507 /// # Examples
508 ///
509 #[cfg_attr(any(target_os = "android", target_os = "linux"), doc = "```no_run")]
510 #[cfg_attr(not(any(target_os = "android", target_os = "linux")), doc = "```ignore")]
511 /// #![feature(unix_socket_ancillary_data)]
512 /// use std::os::unix::net::{UnixStream, SocketAncillary, AncillaryData};
513 /// use std::io::IoSliceMut;
514 ///
515 /// fn main() -> std::io::Result<()> {
516 /// let socket = UnixStream::connect("/tmp/sock")?;
517 /// let mut buf1 = [1; 8];
518 /// let mut buf2 = [2; 16];
519 /// let mut buf3 = [3; 8];
520 /// let mut bufs = &mut [
521 /// IoSliceMut::new(&mut buf1),
522 /// IoSliceMut::new(&mut buf2),
523 /// IoSliceMut::new(&mut buf3),
524 /// ][..];
525 /// let mut fds = [0; 8];
526 /// let mut ancillary_buffer = [0; 128];
527 /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]);
528 /// let size = socket.recv_vectored_with_ancillary(bufs, &mut ancillary)?;
529 /// println!("received {size}");
530 /// for ancillary_result in ancillary.messages() {
531 /// if let AncillaryData::ScmRights(scm_rights) = ancillary_result.unwrap() {
532 /// for fd in scm_rights {
533 /// println!("receive file descriptor: {fd}");
534 /// }
535 /// }
536 /// }
537 /// Ok(())
538 /// }
539 /// ```
540 #[cfg(any(doc, target_os = "android", target_os = "linux"))]
541 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
542 pub fn recv_vectored_with_ancillary(
543 &self,
544 bufs: &mut [IoSliceMut<'_>],
545 ancillary: &mut SocketAncillary<'_>,
546 ) -> io::Result<usize> {
547 let (count, _, _) = recv_vectored_with_ancillary_from(&self.0, bufs, ancillary)?;
548
549 Ok(count)
550 }
551
552 /// Sends data and ancillary data on the socket.
553 ///
554 /// On success, returns the number of bytes written.
555 ///
556 /// # Examples
557 ///
558 #[cfg_attr(any(target_os = "android", target_os = "linux"), doc = "```no_run")]
559 #[cfg_attr(not(any(target_os = "android", target_os = "linux")), doc = "```ignore")]
560 /// #![feature(unix_socket_ancillary_data)]
561 /// use std::os::unix::net::{UnixStream, SocketAncillary};
562 /// use std::io::IoSlice;
563 ///
564 /// fn main() -> std::io::Result<()> {
565 /// let socket = UnixStream::connect("/tmp/sock")?;
566 /// let buf1 = [1; 8];
567 /// let buf2 = [2; 16];
568 /// let buf3 = [3; 8];
569 /// let bufs = &[
570 /// IoSlice::new(&buf1),
571 /// IoSlice::new(&buf2),
572 /// IoSlice::new(&buf3),
573 /// ][..];
574 /// let fds = [0, 1, 2];
575 /// let mut ancillary_buffer = [0; 128];
576 /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]);
577 /// ancillary.add_fds(&fds[..]);
578 /// socket.send_vectored_with_ancillary(bufs, &mut ancillary)
579 /// .expect("send_vectored_with_ancillary function failed");
580 /// Ok(())
581 /// }
582 /// ```
583 #[cfg(any(doc, target_os = "android", target_os = "linux"))]
584 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
585 pub fn send_vectored_with_ancillary(
586 &self,
587 bufs: &[IoSlice<'_>],
588 ancillary: &mut SocketAncillary<'_>,
589 ) -> io::Result<usize> {
590 send_vectored_with_ancillary_to(&self.0, None, bufs, ancillary)
591 }
592}
593
594#[stable(feature = "unix_socket", since = "1.10.0")]
595impl io::Read for UnixStream {
596 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
597 io::Read::read(&mut &*self, buf)
598 }
599
600 fn read_buf(&mut self, buf: io::BorrowedCursor<'_>) -> io::Result<()> {
601 io::Read::read_buf(&mut &*self, buf)
602 }
603
604 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
605 io::Read::read_vectored(&mut &*self, bufs)
606 }
607
608 #[inline]
609 fn is_read_vectored(&self) -> bool {
610 io::Read::is_read_vectored(&&*self)
611 }
612}
613
614#[stable(feature = "unix_socket", since = "1.10.0")]
615impl<'a> io::Read for &'a UnixStream {
616 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
617 self.0.read(buf)
618 }
619
620 fn read_buf(&mut self, buf: io::BorrowedCursor<'_>) -> io::Result<()> {
621 self.0.read_buf(buf)
622 }
623
624 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
625 self.0.read_vectored(bufs)
626 }
627
628 #[inline]
629 fn is_read_vectored(&self) -> bool {
630 self.0.is_read_vectored()
631 }
632}
633
634#[stable(feature = "unix_socket", since = "1.10.0")]
635impl io::Write for UnixStream {
636 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
637 io::Write::write(&mut &*self, buf)
638 }
639
640 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
641 io::Write::write_vectored(&mut &*self, bufs)
642 }
643
644 #[inline]
645 fn is_write_vectored(&self) -> bool {
646 io::Write::is_write_vectored(&&*self)
647 }
648
649 fn flush(&mut self) -> io::Result<()> {
650 io::Write::flush(&mut &*self)
651 }
652}
653
654#[stable(feature = "unix_socket", since = "1.10.0")]
655impl<'a> io::Write for &'a UnixStream {
656 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
657 self.0.send_with_flags(buf, MSG_NOSIGNAL)
658 }
659
660 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
661 self.0.write_vectored(bufs)
662 }
663
664 #[inline]
665 fn is_write_vectored(&self) -> bool {
666 self.0.is_write_vectored()
667 }
668
669 #[inline]
670 fn flush(&mut self) -> io::Result<()> {
671 Ok(())
672 }
673}
674
675#[stable(feature = "unix_socket", since = "1.10.0")]
676impl AsRawFd for UnixStream {
677 #[inline]
678 fn as_raw_fd(&self) -> RawFd {
679 self.0.as_raw_fd()
680 }
681}
682
683#[stable(feature = "unix_socket", since = "1.10.0")]
684impl FromRawFd for UnixStream {
685 #[inline]
686 unsafe fn from_raw_fd(fd: RawFd) -> UnixStream {
687 UnixStream(Socket::from_inner(FromInner::from_inner(OwnedFd::from_raw_fd(fd))))
688 }
689}
690
691#[stable(feature = "unix_socket", since = "1.10.0")]
692impl IntoRawFd for UnixStream {
693 #[inline]
694 fn into_raw_fd(self) -> RawFd {
695 self.0.into_raw_fd()
696 }
697}
698
699#[stable(feature = "io_safety", since = "1.63.0")]
700impl AsFd for UnixStream {
701 #[inline]
702 fn as_fd(&self) -> BorrowedFd<'_> {
703 self.0.as_fd()
704 }
705}
706
707#[stable(feature = "io_safety", since = "1.63.0")]
708impl From<UnixStream> for OwnedFd {
709 /// Takes ownership of a [`UnixStream`]'s socket file descriptor.
710 #[inline]
711 fn from(unix_stream: UnixStream) -> OwnedFd {
712 unsafe { OwnedFd::from_raw_fd(unix_stream.into_raw_fd()) }
713 }
714}
715
716#[stable(feature = "io_safety", since = "1.63.0")]
717impl From<OwnedFd> for UnixStream {
718 #[inline]
719 fn from(owned: OwnedFd) -> Self {
720 unsafe { Self::from_raw_fd(owned.into_raw_fd()) }
721 }
722}
723
724impl AsInner<Socket> for UnixStream {
725 #[inline]
726 fn as_inner(&self) -> &Socket {
727 &self.0
728 }
729}