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