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