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