1 | #[cfg (any( |
2 | target_os = "linux" , |
3 | target_os = "android" , |
4 | target_os = "dragonfly" , |
5 | target_os = "freebsd" , |
6 | target_os = "openbsd" , |
7 | target_os = "netbsd" , |
8 | target_os = "solaris" , |
9 | target_os = "illumos" , |
10 | target_os = "haiku" , |
11 | target_os = "nto" , |
12 | target_os = "cygwin" |
13 | ))] |
14 | use libc::MSG_NOSIGNAL; |
15 | |
16 | use super::{SocketAddr, sockaddr_un}; |
17 | #[cfg (any(doc, target_os = "android" , target_os = "linux" ))] |
18 | use super::{SocketAncillary, recv_vectored_with_ancillary_from, send_vectored_with_ancillary_to}; |
19 | #[cfg (any(doc, target_os = "android" , target_os = "linux" ))] |
20 | use crate::io::{IoSlice, IoSliceMut}; |
21 | use crate::net::Shutdown; |
22 | use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; |
23 | use crate::path::Path; |
24 | use crate::sealed::Sealed; |
25 | use crate::sys::cvt; |
26 | use crate::sys::net::Socket; |
27 | use crate::sys_common::{AsInner, FromInner, IntoInner}; |
28 | use crate::time::Duration; |
29 | use crate::{fmt, io}; |
30 | #[cfg (not(any( |
31 | target_os = "linux" , |
32 | target_os = "android" , |
33 | target_os = "dragonfly" , |
34 | target_os = "freebsd" , |
35 | target_os = "openbsd" , |
36 | target_os = "netbsd" , |
37 | target_os = "solaris" , |
38 | target_os = "illumos" , |
39 | target_os = "haiku" , |
40 | target_os = "nto" , |
41 | target_os = "cygwin" |
42 | )))] |
43 | const MSG_NOSIGNAL: core::ffi::c_int = 0x0; |
44 | |
45 | /// A Unix datagram socket. |
46 | /// |
47 | /// # Examples |
48 | /// |
49 | /// ```no_run |
50 | /// use std::os::unix::net::UnixDatagram; |
51 | /// |
52 | /// fn main() -> std::io::Result<()> { |
53 | /// let socket = UnixDatagram::bind("/path/to/my/socket" )?; |
54 | /// socket.send_to(b"hello world" , "/path/to/other/socket" )?; |
55 | /// let mut buf = [0; 100]; |
56 | /// let (count, address) = socket.recv_from(&mut buf)?; |
57 | /// println!("socket {:?} sent {:?}" , address, &buf[..count]); |
58 | /// Ok(()) |
59 | /// } |
60 | /// ``` |
61 | #[stable (feature = "unix_socket" , since = "1.10.0" )] |
62 | pub struct UnixDatagram(Socket); |
63 | |
64 | /// Allows extension traits within `std`. |
65 | #[unstable (feature = "sealed" , issue = "none" )] |
66 | impl Sealed for UnixDatagram {} |
67 | |
68 | #[stable (feature = "unix_socket" , since = "1.10.0" )] |
69 | impl fmt::Debug for UnixDatagram { |
70 | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
71 | let mut builder: DebugStruct<'_, '_> = fmt.debug_struct(name:"UnixDatagram" ); |
72 | builder.field(name:"fd" , self.0.as_inner()); |
73 | if let Ok(addr: SocketAddr) = self.local_addr() { |
74 | builder.field(name:"local" , &addr); |
75 | } |
76 | if let Ok(addr: SocketAddr) = self.peer_addr() { |
77 | builder.field(name:"peer" , &addr); |
78 | } |
79 | builder.finish() |
80 | } |
81 | } |
82 | |
83 | impl UnixDatagram { |
84 | /// Creates a Unix datagram socket bound to the given path. |
85 | /// |
86 | /// # Examples |
87 | /// |
88 | /// ```no_run |
89 | /// use std::os::unix::net::UnixDatagram; |
90 | /// |
91 | /// let sock = match UnixDatagram::bind("/path/to/the/socket" ) { |
92 | /// Ok(sock) => sock, |
93 | /// Err(e) => { |
94 | /// println!("Couldn't bind: {e:?}" ); |
95 | /// return |
96 | /// } |
97 | /// }; |
98 | /// ``` |
99 | #[stable (feature = "unix_socket" , since = "1.10.0" )] |
100 | pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixDatagram> { |
101 | unsafe { |
102 | let socket = UnixDatagram::unbound()?; |
103 | let (addr, len) = sockaddr_un(path.as_ref())?; |
104 | |
105 | cvt(libc::bind(socket.as_raw_fd(), (&raw const addr) as *const _, len as _))?; |
106 | |
107 | Ok(socket) |
108 | } |
109 | } |
110 | |
111 | /// Creates a Unix datagram socket bound to an address. |
112 | /// |
113 | /// # Examples |
114 | /// |
115 | /// ```no_run |
116 | /// use std::os::unix::net::{UnixDatagram}; |
117 | /// |
118 | /// fn main() -> std::io::Result<()> { |
119 | /// let sock1 = UnixDatagram::bind("path/to/socket" )?; |
120 | /// let addr = sock1.local_addr()?; |
121 | /// |
122 | /// let sock2 = match UnixDatagram::bind_addr(&addr) { |
123 | /// Ok(sock) => sock, |
124 | /// Err(err) => { |
125 | /// println!("Couldn't bind: {err:?}" ); |
126 | /// return Err(err); |
127 | /// } |
128 | /// }; |
129 | /// Ok(()) |
130 | /// } |
131 | /// ``` |
132 | #[stable (feature = "unix_socket_abstract" , since = "1.70.0" )] |
133 | pub fn bind_addr(socket_addr: &SocketAddr) -> io::Result<UnixDatagram> { |
134 | unsafe { |
135 | let socket = UnixDatagram::unbound()?; |
136 | cvt(libc::bind( |
137 | socket.as_raw_fd(), |
138 | (&raw const socket_addr.addr) as *const _, |
139 | socket_addr.len as _, |
140 | ))?; |
141 | Ok(socket) |
142 | } |
143 | } |
144 | |
145 | /// Creates a Unix Datagram socket which is not bound to any address. |
146 | /// |
147 | /// # Examples |
148 | /// |
149 | /// ```no_run |
150 | /// use std::os::unix::net::UnixDatagram; |
151 | /// |
152 | /// let sock = match UnixDatagram::unbound() { |
153 | /// Ok(sock) => sock, |
154 | /// Err(e) => { |
155 | /// println!("Couldn't unbound: {e:?}" ); |
156 | /// return |
157 | /// } |
158 | /// }; |
159 | /// ``` |
160 | #[stable (feature = "unix_socket" , since = "1.10.0" )] |
161 | pub fn unbound() -> io::Result<UnixDatagram> { |
162 | let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_DGRAM)?; |
163 | Ok(UnixDatagram(inner)) |
164 | } |
165 | |
166 | /// Creates an unnamed pair of connected sockets. |
167 | /// |
168 | /// Returns two `UnixDatagrams`s which are connected to each other. |
169 | /// |
170 | /// # Examples |
171 | /// |
172 | /// ```no_run |
173 | /// use std::os::unix::net::UnixDatagram; |
174 | /// |
175 | /// let (sock1, sock2) = match UnixDatagram::pair() { |
176 | /// Ok((sock1, sock2)) => (sock1, sock2), |
177 | /// Err(e) => { |
178 | /// println!("Couldn't unbound: {e:?}" ); |
179 | /// return |
180 | /// } |
181 | /// }; |
182 | /// ``` |
183 | #[stable (feature = "unix_socket" , since = "1.10.0" )] |
184 | pub fn pair() -> io::Result<(UnixDatagram, UnixDatagram)> { |
185 | let (i1, i2) = Socket::new_pair(libc::AF_UNIX, libc::SOCK_DGRAM)?; |
186 | Ok((UnixDatagram(i1), UnixDatagram(i2))) |
187 | } |
188 | |
189 | /// Connects the socket to the specified path address. |
190 | /// |
191 | /// The [`send`] method may be used to send data to the specified address. |
192 | /// [`recv`] and [`recv_from`] will only receive data from that address. |
193 | /// |
194 | /// [`send`]: UnixDatagram::send |
195 | /// [`recv`]: UnixDatagram::recv |
196 | /// [`recv_from`]: UnixDatagram::recv_from |
197 | /// |
198 | /// # Examples |
199 | /// |
200 | /// ```no_run |
201 | /// use std::os::unix::net::UnixDatagram; |
202 | /// |
203 | /// fn main() -> std::io::Result<()> { |
204 | /// let sock = UnixDatagram::unbound()?; |
205 | /// match sock.connect("/path/to/the/socket" ) { |
206 | /// Ok(sock) => sock, |
207 | /// Err(e) => { |
208 | /// println!("Couldn't connect: {e:?}" ); |
209 | /// return Err(e) |
210 | /// } |
211 | /// }; |
212 | /// Ok(()) |
213 | /// } |
214 | /// ``` |
215 | #[stable (feature = "unix_socket" , since = "1.10.0" )] |
216 | pub fn connect<P: AsRef<Path>>(&self, path: P) -> io::Result<()> { |
217 | unsafe { |
218 | let (addr, len) = sockaddr_un(path.as_ref())?; |
219 | |
220 | cvt(libc::connect(self.as_raw_fd(), (&raw const addr) as *const _, len))?; |
221 | } |
222 | Ok(()) |
223 | } |
224 | |
225 | /// Connects the socket to an address. |
226 | /// |
227 | /// # Examples |
228 | /// |
229 | /// ```no_run |
230 | /// use std::os::unix::net::{UnixDatagram}; |
231 | /// |
232 | /// fn main() -> std::io::Result<()> { |
233 | /// let bound = UnixDatagram::bind("/path/to/socket" )?; |
234 | /// let addr = bound.local_addr()?; |
235 | /// |
236 | /// let sock = UnixDatagram::unbound()?; |
237 | /// match sock.connect_addr(&addr) { |
238 | /// Ok(sock) => sock, |
239 | /// Err(e) => { |
240 | /// println!("Couldn't connect: {e:?}" ); |
241 | /// return Err(e) |
242 | /// } |
243 | /// }; |
244 | /// Ok(()) |
245 | /// } |
246 | /// ``` |
247 | #[stable (feature = "unix_socket_abstract" , since = "1.70.0" )] |
248 | pub fn connect_addr(&self, socket_addr: &SocketAddr) -> io::Result<()> { |
249 | unsafe { |
250 | cvt(libc::connect( |
251 | self.as_raw_fd(), |
252 | (&raw const socket_addr.addr) as *const _, |
253 | socket_addr.len, |
254 | ))?; |
255 | } |
256 | Ok(()) |
257 | } |
258 | |
259 | /// Creates a new independently owned handle to the underlying socket. |
260 | /// |
261 | /// The returned `UnixDatagram` is a reference to the same socket that this |
262 | /// object references. Both handles can be used to accept incoming |
263 | /// connections and options set on one side will affect the other. |
264 | /// |
265 | /// # Examples |
266 | /// |
267 | /// ```no_run |
268 | /// use std::os::unix::net::UnixDatagram; |
269 | /// |
270 | /// fn main() -> std::io::Result<()> { |
271 | /// let sock = UnixDatagram::bind("/path/to/the/socket" )?; |
272 | /// let sock_copy = sock.try_clone().expect("try_clone failed" ); |
273 | /// Ok(()) |
274 | /// } |
275 | /// ``` |
276 | #[stable (feature = "unix_socket" , since = "1.10.0" )] |
277 | pub fn try_clone(&self) -> io::Result<UnixDatagram> { |
278 | self.0.duplicate().map(UnixDatagram) |
279 | } |
280 | |
281 | /// Returns the address of this socket. |
282 | /// |
283 | /// # Examples |
284 | /// |
285 | /// ```no_run |
286 | /// use std::os::unix::net::UnixDatagram; |
287 | /// |
288 | /// fn main() -> std::io::Result<()> { |
289 | /// let sock = UnixDatagram::bind("/path/to/the/socket" )?; |
290 | /// let addr = sock.local_addr().expect("Couldn't get local address" ); |
291 | /// Ok(()) |
292 | /// } |
293 | /// ``` |
294 | #[stable (feature = "unix_socket" , since = "1.10.0" )] |
295 | pub fn local_addr(&self) -> io::Result<SocketAddr> { |
296 | SocketAddr::new(|addr, len| unsafe { libc::getsockname(self.as_raw_fd(), addr, len) }) |
297 | } |
298 | |
299 | /// Returns the address of this socket's peer. |
300 | /// |
301 | /// The [`connect`] method will connect the socket to a peer. |
302 | /// |
303 | /// [`connect`]: UnixDatagram::connect |
304 | /// |
305 | /// # Examples |
306 | /// |
307 | /// ```no_run |
308 | /// use std::os::unix::net::UnixDatagram; |
309 | /// |
310 | /// fn main() -> std::io::Result<()> { |
311 | /// let sock = UnixDatagram::unbound()?; |
312 | /// sock.connect("/path/to/the/socket" )?; |
313 | /// |
314 | /// let addr = sock.peer_addr().expect("Couldn't get peer address" ); |
315 | /// Ok(()) |
316 | /// } |
317 | /// ``` |
318 | #[stable (feature = "unix_socket" , since = "1.10.0" )] |
319 | pub fn peer_addr(&self) -> io::Result<SocketAddr> { |
320 | SocketAddr::new(|addr, len| unsafe { libc::getpeername(self.as_raw_fd(), addr, len) }) |
321 | } |
322 | |
323 | fn recv_from_flags( |
324 | &self, |
325 | buf: &mut [u8], |
326 | flags: core::ffi::c_int, |
327 | ) -> io::Result<(usize, SocketAddr)> { |
328 | let mut count = 0; |
329 | let addr = SocketAddr::new(|addr, len| unsafe { |
330 | count = libc::recvfrom( |
331 | self.as_raw_fd(), |
332 | buf.as_mut_ptr() as *mut _, |
333 | buf.len(), |
334 | flags, |
335 | addr, |
336 | len, |
337 | ); |
338 | if count > 0 { |
339 | 1 |
340 | } else if count == 0 { |
341 | 0 |
342 | } else { |
343 | -1 |
344 | } |
345 | })?; |
346 | |
347 | Ok((count as usize, addr)) |
348 | } |
349 | |
350 | /// Receives data from the socket. |
351 | /// |
352 | /// On success, returns the number of bytes read and the address from |
353 | /// whence the data came. |
354 | /// |
355 | /// # Examples |
356 | /// |
357 | /// ```no_run |
358 | /// use std::os::unix::net::UnixDatagram; |
359 | /// |
360 | /// fn main() -> std::io::Result<()> { |
361 | /// let sock = UnixDatagram::unbound()?; |
362 | /// let mut buf = vec![0; 10]; |
363 | /// let (size, sender) = sock.recv_from(buf.as_mut_slice())?; |
364 | /// println!("received {size} bytes from {sender:?}" ); |
365 | /// Ok(()) |
366 | /// } |
367 | /// ``` |
368 | #[stable (feature = "unix_socket" , since = "1.10.0" )] |
369 | pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { |
370 | self.recv_from_flags(buf, 0) |
371 | } |
372 | |
373 | /// Receives data from the socket. |
374 | /// |
375 | /// On success, returns the number of bytes read. |
376 | /// |
377 | /// # Examples |
378 | /// |
379 | /// ```no_run |
380 | /// use std::os::unix::net::UnixDatagram; |
381 | /// |
382 | /// fn main() -> std::io::Result<()> { |
383 | /// let sock = UnixDatagram::bind("/path/to/the/socket" )?; |
384 | /// let mut buf = vec![0; 10]; |
385 | /// sock.recv(buf.as_mut_slice()).expect("recv function failed" ); |
386 | /// Ok(()) |
387 | /// } |
388 | /// ``` |
389 | #[stable (feature = "unix_socket" , since = "1.10.0" )] |
390 | pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> { |
391 | self.0.read(buf) |
392 | } |
393 | |
394 | /// Receives data and ancillary data from socket. |
395 | /// |
396 | /// On success, returns the number of bytes read, if the data was truncated and the address from whence the msg came. |
397 | /// |
398 | /// # Examples |
399 | /// |
400 | #[cfg_attr (any(target_os = "android" , target_os = "linux" ), doc = "```no_run" )] |
401 | #[cfg_attr (not(any(target_os = "android" , target_os = "linux" )), doc = "```ignore" )] |
402 | /// #![feature(unix_socket_ancillary_data)] |
403 | /// use std::os::unix::net::{UnixDatagram, SocketAncillary, AncillaryData}; |
404 | /// use std::io::IoSliceMut; |
405 | /// |
406 | /// fn main() -> std::io::Result<()> { |
407 | /// let sock = UnixDatagram::unbound()?; |
408 | /// let mut buf1 = [1; 8]; |
409 | /// let mut buf2 = [2; 16]; |
410 | /// let mut buf3 = [3; 8]; |
411 | /// let mut bufs = &mut [ |
412 | /// IoSliceMut::new(&mut buf1), |
413 | /// IoSliceMut::new(&mut buf2), |
414 | /// IoSliceMut::new(&mut buf3), |
415 | /// ][..]; |
416 | /// let mut fds = [0; 8]; |
417 | /// let mut ancillary_buffer = [0; 128]; |
418 | /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]); |
419 | /// let (size, _truncated, sender) = sock.recv_vectored_with_ancillary_from(bufs, &mut ancillary)?; |
420 | /// println!("received {size}" ); |
421 | /// for ancillary_result in ancillary.messages() { |
422 | /// if let AncillaryData::ScmRights(scm_rights) = ancillary_result.unwrap() { |
423 | /// for fd in scm_rights { |
424 | /// println!("receive file descriptor: {fd}" ); |
425 | /// } |
426 | /// } |
427 | /// } |
428 | /// Ok(()) |
429 | /// } |
430 | /// ``` |
431 | #[cfg (any(doc, target_os = "android" , target_os = "linux" ))] |
432 | #[unstable (feature = "unix_socket_ancillary_data" , issue = "76915" )] |
433 | pub fn recv_vectored_with_ancillary_from( |
434 | &self, |
435 | bufs: &mut [IoSliceMut<'_>], |
436 | ancillary: &mut SocketAncillary<'_>, |
437 | ) -> io::Result<(usize, bool, SocketAddr)> { |
438 | let (count, truncated, addr) = recv_vectored_with_ancillary_from(&self.0, bufs, ancillary)?; |
439 | let addr = addr?; |
440 | |
441 | Ok((count, truncated, addr)) |
442 | } |
443 | |
444 | /// Receives data and ancillary data from socket. |
445 | /// |
446 | /// On success, returns the number of bytes read and if the data was truncated. |
447 | /// |
448 | /// # Examples |
449 | /// |
450 | #[cfg_attr (any(target_os = "android" , target_os = "linux" ), doc = "```no_run" )] |
451 | #[cfg_attr (not(any(target_os = "android" , target_os = "linux" )), doc = "```ignore" )] |
452 | /// #![feature(unix_socket_ancillary_data)] |
453 | /// use std::os::unix::net::{UnixDatagram, SocketAncillary, AncillaryData}; |
454 | /// use std::io::IoSliceMut; |
455 | /// |
456 | /// fn main() -> std::io::Result<()> { |
457 | /// let sock = UnixDatagram::unbound()?; |
458 | /// let mut buf1 = [1; 8]; |
459 | /// let mut buf2 = [2; 16]; |
460 | /// let mut buf3 = [3; 8]; |
461 | /// let mut bufs = &mut [ |
462 | /// IoSliceMut::new(&mut buf1), |
463 | /// IoSliceMut::new(&mut buf2), |
464 | /// IoSliceMut::new(&mut buf3), |
465 | /// ][..]; |
466 | /// let mut fds = [0; 8]; |
467 | /// let mut ancillary_buffer = [0; 128]; |
468 | /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]); |
469 | /// let (size, _truncated) = sock.recv_vectored_with_ancillary(bufs, &mut ancillary)?; |
470 | /// println!("received {size}" ); |
471 | /// for ancillary_result in ancillary.messages() { |
472 | /// if let AncillaryData::ScmRights(scm_rights) = ancillary_result.unwrap() { |
473 | /// for fd in scm_rights { |
474 | /// println!("receive file descriptor: {fd}" ); |
475 | /// } |
476 | /// } |
477 | /// } |
478 | /// Ok(()) |
479 | /// } |
480 | /// ``` |
481 | #[cfg (any(doc, target_os = "android" , target_os = "linux" ))] |
482 | #[unstable (feature = "unix_socket_ancillary_data" , issue = "76915" )] |
483 | pub fn recv_vectored_with_ancillary( |
484 | &self, |
485 | bufs: &mut [IoSliceMut<'_>], |
486 | ancillary: &mut SocketAncillary<'_>, |
487 | ) -> io::Result<(usize, bool)> { |
488 | let (count, truncated, addr) = recv_vectored_with_ancillary_from(&self.0, bufs, ancillary)?; |
489 | addr?; |
490 | |
491 | Ok((count, truncated)) |
492 | } |
493 | |
494 | /// Sends data on the socket to the specified address. |
495 | /// |
496 | /// On success, returns the number of bytes written. |
497 | /// |
498 | /// # Examples |
499 | /// |
500 | /// ```no_run |
501 | /// use std::os::unix::net::UnixDatagram; |
502 | /// |
503 | /// fn main() -> std::io::Result<()> { |
504 | /// let sock = UnixDatagram::unbound()?; |
505 | /// sock.send_to(b"omelette au fromage" , "/some/sock" ).expect("send_to function failed" ); |
506 | /// Ok(()) |
507 | /// } |
508 | /// ``` |
509 | #[stable (feature = "unix_socket" , since = "1.10.0" )] |
510 | pub fn send_to<P: AsRef<Path>>(&self, buf: &[u8], path: P) -> io::Result<usize> { |
511 | unsafe { |
512 | let (addr, len) = sockaddr_un(path.as_ref())?; |
513 | |
514 | let count = cvt(libc::sendto( |
515 | self.as_raw_fd(), |
516 | buf.as_ptr() as *const _, |
517 | buf.len(), |
518 | MSG_NOSIGNAL, |
519 | (&raw const addr) as *const _, |
520 | len, |
521 | ))?; |
522 | Ok(count as usize) |
523 | } |
524 | } |
525 | |
526 | /// Sends data on the socket to the specified [SocketAddr]. |
527 | /// |
528 | /// On success, returns the number of bytes written. |
529 | /// |
530 | /// [SocketAddr]: crate::os::unix::net::SocketAddr |
531 | /// |
532 | /// # Examples |
533 | /// |
534 | /// ```no_run |
535 | /// use std::os::unix::net::{UnixDatagram}; |
536 | /// |
537 | /// fn main() -> std::io::Result<()> { |
538 | /// let bound = UnixDatagram::bind("/path/to/socket" )?; |
539 | /// let addr = bound.local_addr()?; |
540 | /// |
541 | /// let sock = UnixDatagram::unbound()?; |
542 | /// sock.send_to_addr(b"bacon egg and cheese" , &addr).expect("send_to_addr function failed" ); |
543 | /// Ok(()) |
544 | /// } |
545 | /// ``` |
546 | #[stable (feature = "unix_socket_abstract" , since = "1.70.0" )] |
547 | pub fn send_to_addr(&self, buf: &[u8], socket_addr: &SocketAddr) -> io::Result<usize> { |
548 | unsafe { |
549 | let count = cvt(libc::sendto( |
550 | self.as_raw_fd(), |
551 | buf.as_ptr() as *const _, |
552 | buf.len(), |
553 | MSG_NOSIGNAL, |
554 | (&raw const socket_addr.addr) as *const _, |
555 | socket_addr.len, |
556 | ))?; |
557 | Ok(count as usize) |
558 | } |
559 | } |
560 | |
561 | /// Sends data on the socket to the socket's peer. |
562 | /// |
563 | /// The peer address may be set by the `connect` method, and this method |
564 | /// will return an error if the socket has not already been connected. |
565 | /// |
566 | /// On success, returns the number of bytes written. |
567 | /// |
568 | /// # Examples |
569 | /// |
570 | /// ```no_run |
571 | /// use std::os::unix::net::UnixDatagram; |
572 | /// |
573 | /// fn main() -> std::io::Result<()> { |
574 | /// let sock = UnixDatagram::unbound()?; |
575 | /// sock.connect("/some/sock" ).expect("Couldn't connect" ); |
576 | /// sock.send(b"omelette au fromage" ).expect("send_to function failed" ); |
577 | /// Ok(()) |
578 | /// } |
579 | /// ``` |
580 | #[stable (feature = "unix_socket" , since = "1.10.0" )] |
581 | pub fn send(&self, buf: &[u8]) -> io::Result<usize> { |
582 | self.0.write(buf) |
583 | } |
584 | |
585 | /// Sends data and ancillary data on the socket to the specified address. |
586 | /// |
587 | /// On success, returns the number of bytes written. |
588 | /// |
589 | /// # Examples |
590 | /// |
591 | #[cfg_attr (any(target_os = "android" , target_os = "linux" ), doc = "```no_run" )] |
592 | #[cfg_attr (not(any(target_os = "android" , target_os = "linux" )), doc = "```ignore" )] |
593 | /// #![feature(unix_socket_ancillary_data)] |
594 | /// use std::os::unix::net::{UnixDatagram, SocketAncillary}; |
595 | /// use std::io::IoSlice; |
596 | /// |
597 | /// fn main() -> std::io::Result<()> { |
598 | /// let sock = UnixDatagram::unbound()?; |
599 | /// let buf1 = [1; 8]; |
600 | /// let buf2 = [2; 16]; |
601 | /// let buf3 = [3; 8]; |
602 | /// let bufs = &[ |
603 | /// IoSlice::new(&buf1), |
604 | /// IoSlice::new(&buf2), |
605 | /// IoSlice::new(&buf3), |
606 | /// ][..]; |
607 | /// let fds = [0, 1, 2]; |
608 | /// let mut ancillary_buffer = [0; 128]; |
609 | /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]); |
610 | /// ancillary.add_fds(&fds[..]); |
611 | /// sock.send_vectored_with_ancillary_to(bufs, &mut ancillary, "/some/sock" ) |
612 | /// .expect("send_vectored_with_ancillary_to function failed" ); |
613 | /// Ok(()) |
614 | /// } |
615 | /// ``` |
616 | #[cfg (any(doc, target_os = "android" , target_os = "linux" ))] |
617 | #[unstable (feature = "unix_socket_ancillary_data" , issue = "76915" )] |
618 | pub fn send_vectored_with_ancillary_to<P: AsRef<Path>>( |
619 | &self, |
620 | bufs: &[IoSlice<'_>], |
621 | ancillary: &mut SocketAncillary<'_>, |
622 | path: P, |
623 | ) -> io::Result<usize> { |
624 | send_vectored_with_ancillary_to(&self.0, Some(path.as_ref()), bufs, ancillary) |
625 | } |
626 | |
627 | /// Sends data and ancillary data on the socket. |
628 | /// |
629 | /// On success, returns the number of bytes written. |
630 | /// |
631 | /// # Examples |
632 | /// |
633 | #[cfg_attr (any(target_os = "android" , target_os = "linux" ), doc = "```no_run" )] |
634 | #[cfg_attr (not(any(target_os = "android" , target_os = "linux" )), doc = "```ignore" )] |
635 | /// #![feature(unix_socket_ancillary_data)] |
636 | /// use std::os::unix::net::{UnixDatagram, SocketAncillary}; |
637 | /// use std::io::IoSlice; |
638 | /// |
639 | /// fn main() -> std::io::Result<()> { |
640 | /// let sock = UnixDatagram::unbound()?; |
641 | /// let buf1 = [1; 8]; |
642 | /// let buf2 = [2; 16]; |
643 | /// let buf3 = [3; 8]; |
644 | /// let bufs = &[ |
645 | /// IoSlice::new(&buf1), |
646 | /// IoSlice::new(&buf2), |
647 | /// IoSlice::new(&buf3), |
648 | /// ][..]; |
649 | /// let fds = [0, 1, 2]; |
650 | /// let mut ancillary_buffer = [0; 128]; |
651 | /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]); |
652 | /// ancillary.add_fds(&fds[..]); |
653 | /// sock.send_vectored_with_ancillary(bufs, &mut ancillary) |
654 | /// .expect("send_vectored_with_ancillary function failed" ); |
655 | /// Ok(()) |
656 | /// } |
657 | /// ``` |
658 | #[cfg (any(doc, target_os = "android" , target_os = "linux" ))] |
659 | #[unstable (feature = "unix_socket_ancillary_data" , issue = "76915" )] |
660 | pub fn send_vectored_with_ancillary( |
661 | &self, |
662 | bufs: &[IoSlice<'_>], |
663 | ancillary: &mut SocketAncillary<'_>, |
664 | ) -> io::Result<usize> { |
665 | send_vectored_with_ancillary_to(&self.0, None, bufs, ancillary) |
666 | } |
667 | |
668 | /// Sets the read timeout for the socket. |
669 | /// |
670 | /// If the provided value is [`None`], then [`recv`] and [`recv_from`] calls will |
671 | /// block indefinitely. An [`Err`] is returned if the zero [`Duration`] |
672 | /// is passed to this method. |
673 | /// |
674 | /// [`recv`]: UnixDatagram::recv |
675 | /// [`recv_from`]: UnixDatagram::recv_from |
676 | /// |
677 | /// # Examples |
678 | /// |
679 | /// ``` |
680 | /// use std::os::unix::net::UnixDatagram; |
681 | /// use std::time::Duration; |
682 | /// |
683 | /// fn main() -> std::io::Result<()> { |
684 | /// let sock = UnixDatagram::unbound()?; |
685 | /// sock.set_read_timeout(Some(Duration::new(1, 0))) |
686 | /// .expect("set_read_timeout function failed" ); |
687 | /// Ok(()) |
688 | /// } |
689 | /// ``` |
690 | /// |
691 | /// An [`Err`] is returned if the zero [`Duration`] is passed to this |
692 | /// method: |
693 | /// |
694 | /// ```no_run |
695 | /// use std::io; |
696 | /// use std::os::unix::net::UnixDatagram; |
697 | /// use std::time::Duration; |
698 | /// |
699 | /// fn main() -> std::io::Result<()> { |
700 | /// let socket = UnixDatagram::unbound()?; |
701 | /// let result = socket.set_read_timeout(Some(Duration::new(0, 0))); |
702 | /// let err = result.unwrap_err(); |
703 | /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput); |
704 | /// Ok(()) |
705 | /// } |
706 | /// ``` |
707 | #[stable (feature = "unix_socket" , since = "1.10.0" )] |
708 | pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> { |
709 | self.0.set_timeout(timeout, libc::SO_RCVTIMEO) |
710 | } |
711 | |
712 | /// Sets the write timeout for the socket. |
713 | /// |
714 | /// If the provided value is [`None`], then [`send`] and [`send_to`] calls will |
715 | /// block indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this |
716 | /// method. |
717 | /// |
718 | /// [`send`]: UnixDatagram::send |
719 | /// [`send_to`]: UnixDatagram::send_to |
720 | /// |
721 | /// # Examples |
722 | /// |
723 | /// ``` |
724 | /// use std::os::unix::net::UnixDatagram; |
725 | /// use std::time::Duration; |
726 | /// |
727 | /// fn main() -> std::io::Result<()> { |
728 | /// let sock = UnixDatagram::unbound()?; |
729 | /// sock.set_write_timeout(Some(Duration::new(1, 0))) |
730 | /// .expect("set_write_timeout function failed" ); |
731 | /// Ok(()) |
732 | /// } |
733 | /// ``` |
734 | /// |
735 | /// An [`Err`] is returned if the zero [`Duration`] is passed to this |
736 | /// method: |
737 | /// |
738 | /// ```no_run |
739 | /// use std::io; |
740 | /// use std::os::unix::net::UnixDatagram; |
741 | /// use std::time::Duration; |
742 | /// |
743 | /// fn main() -> std::io::Result<()> { |
744 | /// let socket = UnixDatagram::unbound()?; |
745 | /// let result = socket.set_write_timeout(Some(Duration::new(0, 0))); |
746 | /// let err = result.unwrap_err(); |
747 | /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput); |
748 | /// Ok(()) |
749 | /// } |
750 | /// ``` |
751 | #[stable (feature = "unix_socket" , since = "1.10.0" )] |
752 | pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> { |
753 | self.0.set_timeout(timeout, libc::SO_SNDTIMEO) |
754 | } |
755 | |
756 | /// Returns the read timeout of this socket. |
757 | /// |
758 | /// # Examples |
759 | /// |
760 | /// ``` |
761 | /// use std::os::unix::net::UnixDatagram; |
762 | /// use std::time::Duration; |
763 | /// |
764 | /// fn main() -> std::io::Result<()> { |
765 | /// let sock = UnixDatagram::unbound()?; |
766 | /// sock.set_read_timeout(Some(Duration::new(1, 0))) |
767 | /// .expect("set_read_timeout function failed" ); |
768 | /// assert_eq!(sock.read_timeout()?, Some(Duration::new(1, 0))); |
769 | /// Ok(()) |
770 | /// } |
771 | /// ``` |
772 | #[stable (feature = "unix_socket" , since = "1.10.0" )] |
773 | pub fn read_timeout(&self) -> io::Result<Option<Duration>> { |
774 | self.0.timeout(libc::SO_RCVTIMEO) |
775 | } |
776 | |
777 | /// Returns the write timeout of this socket. |
778 | /// |
779 | /// # Examples |
780 | /// |
781 | /// ``` |
782 | /// use std::os::unix::net::UnixDatagram; |
783 | /// use std::time::Duration; |
784 | /// |
785 | /// fn main() -> std::io::Result<()> { |
786 | /// let sock = UnixDatagram::unbound()?; |
787 | /// sock.set_write_timeout(Some(Duration::new(1, 0))) |
788 | /// .expect("set_write_timeout function failed" ); |
789 | /// assert_eq!(sock.write_timeout()?, Some(Duration::new(1, 0))); |
790 | /// Ok(()) |
791 | /// } |
792 | /// ``` |
793 | #[stable (feature = "unix_socket" , since = "1.10.0" )] |
794 | pub fn write_timeout(&self) -> io::Result<Option<Duration>> { |
795 | self.0.timeout(libc::SO_SNDTIMEO) |
796 | } |
797 | |
798 | /// Moves the socket into or out of nonblocking mode. |
799 | /// |
800 | /// # Examples |
801 | /// |
802 | /// ``` |
803 | /// use std::os::unix::net::UnixDatagram; |
804 | /// |
805 | /// fn main() -> std::io::Result<()> { |
806 | /// let sock = UnixDatagram::unbound()?; |
807 | /// sock.set_nonblocking(true).expect("set_nonblocking function failed" ); |
808 | /// Ok(()) |
809 | /// } |
810 | /// ``` |
811 | #[stable (feature = "unix_socket" , since = "1.10.0" )] |
812 | pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { |
813 | self.0.set_nonblocking(nonblocking) |
814 | } |
815 | |
816 | /// Set the id of the socket for network filtering purpose |
817 | /// |
818 | #[cfg_attr ( |
819 | any(target_os = "linux" , target_os = "freebsd" , target_os = "openbsd" ), |
820 | doc = "```no_run" |
821 | )] |
822 | #[cfg_attr ( |
823 | not(any(target_os = "linux" , target_os = "freebsd" , target_os = "openbsd" )), |
824 | doc = "```ignore" |
825 | )] |
826 | /// #![feature(unix_set_mark)] |
827 | /// use std::os::unix::net::UnixDatagram; |
828 | /// |
829 | /// fn main() -> std::io::Result<()> { |
830 | /// let sock = UnixDatagram::unbound()?; |
831 | /// sock.set_mark(32)?; |
832 | /// Ok(()) |
833 | /// } |
834 | /// ``` |
835 | #[cfg (any(doc, target_os = "linux" , target_os = "freebsd" , target_os = "openbsd" ,))] |
836 | #[unstable (feature = "unix_set_mark" , issue = "96467" )] |
837 | pub fn set_mark(&self, mark: u32) -> io::Result<()> { |
838 | self.0.set_mark(mark) |
839 | } |
840 | |
841 | /// Returns the value of the `SO_ERROR` option. |
842 | /// |
843 | /// # Examples |
844 | /// |
845 | /// ```no_run |
846 | /// use std::os::unix::net::UnixDatagram; |
847 | /// |
848 | /// fn main() -> std::io::Result<()> { |
849 | /// let sock = UnixDatagram::unbound()?; |
850 | /// if let Ok(Some(err)) = sock.take_error() { |
851 | /// println!("Got error: {err:?}" ); |
852 | /// } |
853 | /// Ok(()) |
854 | /// } |
855 | /// ``` |
856 | #[stable (feature = "unix_socket" , since = "1.10.0" )] |
857 | pub fn take_error(&self) -> io::Result<Option<io::Error>> { |
858 | self.0.take_error() |
859 | } |
860 | |
861 | /// Shut down the read, write, or both halves of this connection. |
862 | /// |
863 | /// This function will cause all pending and future I/O calls on the |
864 | /// specified portions to immediately return with an appropriate value |
865 | /// (see the documentation of [`Shutdown`]). |
866 | /// |
867 | /// ```no_run |
868 | /// use std::os::unix::net::UnixDatagram; |
869 | /// use std::net::Shutdown; |
870 | /// |
871 | /// fn main() -> std::io::Result<()> { |
872 | /// let sock = UnixDatagram::unbound()?; |
873 | /// sock.shutdown(Shutdown::Both).expect("shutdown function failed" ); |
874 | /// Ok(()) |
875 | /// } |
876 | /// ``` |
877 | #[stable (feature = "unix_socket" , since = "1.10.0" )] |
878 | pub fn shutdown(&self, how: Shutdown) -> io::Result<()> { |
879 | self.0.shutdown(how) |
880 | } |
881 | |
882 | /// Receives data on the socket from the remote address to which it is |
883 | /// connected, without removing that data from the queue. On success, |
884 | /// returns the number of bytes peeked. |
885 | /// |
886 | /// Successive calls return the same data. This is accomplished by passing |
887 | /// `MSG_PEEK` as a flag to the underlying `recv` system call. |
888 | /// |
889 | /// # Examples |
890 | /// |
891 | /// ```no_run |
892 | /// #![feature(unix_socket_peek)] |
893 | /// |
894 | /// use std::os::unix::net::UnixDatagram; |
895 | /// |
896 | /// fn main() -> std::io::Result<()> { |
897 | /// let socket = UnixDatagram::bind("/tmp/sock" )?; |
898 | /// let mut buf = [0; 10]; |
899 | /// let len = socket.peek(&mut buf).expect("peek failed" ); |
900 | /// Ok(()) |
901 | /// } |
902 | /// ``` |
903 | #[unstable (feature = "unix_socket_peek" , issue = "76923" )] |
904 | pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> { |
905 | self.0.peek(buf) |
906 | } |
907 | |
908 | /// Receives a single datagram message on the socket, without removing it from the |
909 | /// queue. On success, returns the number of bytes read and the origin. |
910 | /// |
911 | /// The function must be called with valid byte array `buf` of sufficient size to |
912 | /// hold the message bytes. If a message is too long to fit in the supplied buffer, |
913 | /// excess bytes may be discarded. |
914 | /// |
915 | /// Successive calls return the same data. This is accomplished by passing |
916 | /// `MSG_PEEK` as a flag to the underlying `recvfrom` system call. |
917 | /// |
918 | /// Do not use this function to implement busy waiting, instead use `libc::poll` to |
919 | /// synchronize IO events on one or more sockets. |
920 | /// |
921 | /// # Examples |
922 | /// |
923 | /// ```no_run |
924 | /// #![feature(unix_socket_peek)] |
925 | /// |
926 | /// use std::os::unix::net::UnixDatagram; |
927 | /// |
928 | /// fn main() -> std::io::Result<()> { |
929 | /// let socket = UnixDatagram::bind("/tmp/sock" )?; |
930 | /// let mut buf = [0; 10]; |
931 | /// let (len, addr) = socket.peek_from(&mut buf).expect("peek failed" ); |
932 | /// Ok(()) |
933 | /// } |
934 | /// ``` |
935 | #[unstable (feature = "unix_socket_peek" , issue = "76923" )] |
936 | pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { |
937 | self.recv_from_flags(buf, libc::MSG_PEEK) |
938 | } |
939 | } |
940 | |
941 | #[stable (feature = "unix_socket" , since = "1.10.0" )] |
942 | impl AsRawFd for UnixDatagram { |
943 | #[inline ] |
944 | fn as_raw_fd(&self) -> RawFd { |
945 | self.0.as_inner().as_raw_fd() |
946 | } |
947 | } |
948 | |
949 | #[stable (feature = "unix_socket" , since = "1.10.0" )] |
950 | impl FromRawFd for UnixDatagram { |
951 | #[inline ] |
952 | unsafe fn from_raw_fd(fd: RawFd) -> UnixDatagram { |
953 | UnixDatagram(Socket::from_inner(FromInner::from_inner(OwnedFd::from_raw_fd(fd)))) |
954 | } |
955 | } |
956 | |
957 | #[stable (feature = "unix_socket" , since = "1.10.0" )] |
958 | impl IntoRawFd for UnixDatagram { |
959 | #[inline ] |
960 | fn into_raw_fd(self) -> RawFd { |
961 | self.0.into_inner().into_inner().into_raw_fd() |
962 | } |
963 | } |
964 | |
965 | #[stable (feature = "io_safety" , since = "1.63.0" )] |
966 | impl AsFd for UnixDatagram { |
967 | #[inline ] |
968 | fn as_fd(&self) -> BorrowedFd<'_> { |
969 | self.0.as_inner().as_fd() |
970 | } |
971 | } |
972 | |
973 | #[stable (feature = "io_safety" , since = "1.63.0" )] |
974 | impl From<UnixDatagram> for OwnedFd { |
975 | /// Takes ownership of a [`UnixDatagram`]'s socket file descriptor. |
976 | #[inline ] |
977 | fn from(unix_datagram: UnixDatagram) -> OwnedFd { |
978 | unsafe { OwnedFd::from_raw_fd(unix_datagram.into_raw_fd()) } |
979 | } |
980 | } |
981 | |
982 | #[stable (feature = "io_safety" , since = "1.63.0" )] |
983 | impl From<OwnedFd> for UnixDatagram { |
984 | #[inline ] |
985 | fn from(owned: OwnedFd) -> Self { |
986 | unsafe { Self::from_raw_fd(owned.into_raw_fd()) } |
987 | } |
988 | } |
989 | |
990 | impl AsInner<Socket> for UnixDatagram { |
991 | #[inline ] |
992 | fn as_inner(&self) -> &Socket { |
993 | &self.0 |
994 | } |
995 | } |
996 | |