uds_fork/seqpacket.rs
1#[cfg(any(
2 target_vendor="apple", target_os="freebsd",
3 target_os="netbsd",
4 target_os="illumos", target_os="solaris",
5))]
6use std::io::ErrorKind;
7use std::
8{
9 io::{self, ErrorKind, IoSlice, IoSliceMut}, net::Shutdown, ops::{Deref, DerefMut}, os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}, path::Path, time::Duration
10};
11
12#[cfg(feature = "unsatable_preview")]
13use std::os::unix::net::SocketAncillary;
14
15use libc::{MSG_EOR, MSG_PEEK, c_void, send, recv};
16
17//use crate::addr::*;
18use crate::{UnixSocketAddr, helpers::*};
19use crate::ancillary::*;
20use crate::credentials::*;
21
22/// An unix domain sequential packet connection.
23///
24/// Sequential-packet connections have an interface similar to streams,
25/// but behave more like connected datagram sockets.
26///
27/// They have guaranteed in-order and reliable delivery,
28/// which unix datagrams technically doesn't.
29///
30/// # Operating system support
31///
32/// Sequential-packet sockets are supported by Linux, FreeBSD, NetBSD
33/// and Illumos, but not by for example macOS or OpenBSD.
34///
35/// # Zero-length packets
36///
37/// ... are best avoided:
38/// On Linux and FreeBSD zero-length packets can be sent and received,
39/// but there is no way to distinguish receiving one from reaching
40/// end of connection unless the packet has an ancillary payload.
41/// Also beware of trying to receive with a zero-length buffer,
42/// as that will on FreeBSD (and probably other BSDs with seqpacket sockets)
43/// always succeed even if there is no packet waiting.
44///
45/// Illumos and Solaris doesn't support receiving zero-length packets at all:
46/// writes succeed but recv() will block.
47///
48/// # Registering with Xio (xio-rs) a feature = "xio-rs"
49///
50/// A `XioEventPipe` is implemented on this function. During initial registration
51/// an attempt set `nonblocking` mode is performed during initial registration.
52///
53/// See examples below.
54///
55/// # Registering with Mio (mio) a feature = "mio"
56///
57/// A `Source` is implemented on the instance.During initial registration
58/// an attempt set `nonblocking` mode is performed during initial registration.
59///
60/// # Examples
61///
62/// What is sent separately is received separately:
63///
64#[cfg_attr(not(target_vendor="apple"), doc="```")]
65#[cfg_attr(target_vendor="apple", doc="```no_run")]
66/// let (a, b) = uds_fork::UnixSeqpacketConn::pair().expect("Cannot create seqpacket pair");
67///
68/// a.send(b"first").unwrap();
69/// a.send(b"second").unwrap();
70///
71/// let mut buffer_big_enough_for_both = [0; 20];
72/// let len = b.recv(&mut buffer_big_enough_for_both).unwrap();
73/// assert_eq!(&buffer_big_enough_for_both[..len], b"first");
74/// let len = b.recv(&mut buffer_big_enough_for_both).unwrap();
75/// assert_eq!(&buffer_big_enough_for_both[..len], b"second");
76/// ```
77///
78/// Connect to a listener on a socket file and write to it:
79///
80#[cfg_attr(not(target_vendor="apple"), doc="```")]
81#[cfg_attr(target_vendor="apple", doc="```no_run")]
82/// use uds_fork::{UnixSeqpacketListener, UnixSeqpacketConn};
83/// use tempfile::TempDir;
84///
85/// let dir = tempfile::tempdir().unwrap();
86/// let mut file_path = dir.path().join("seqpacket.socket");
87///
88/// let listener = UnixSeqpacketListener::bind(&file_path)
89/// .expect("create seqpacket listener");
90/// let conn = UnixSeqpacketConn::connect(&file_path)
91/// .expect("connect to seqpacket listener");
92///
93/// let message = "Hello, listener";
94/// let sent = conn.send(message.as_bytes()).unwrap();
95/// assert_eq!(sent, message.len());
96/// ```
97///
98/// Connect to a listener on an abstract address:
99///
100#[cfg_attr(any(target_os="linux", target_os="android"), doc="```")]
101#[cfg_attr(not(any(target_os="linux", target_os="android")), doc="```no_run")]
102/// use uds_fork::{UnixSeqpacketListener, UnixSeqpacketConn, UnixSocketAddr};
103///
104/// let addr = UnixSocketAddr::new("@seqpacket example").unwrap();
105/// let listener = UnixSeqpacketListener::bind_unix_addr(&addr)
106/// .expect("create abstract seqpacket listener");
107/// let _client = UnixSeqpacketConn::connect_unix_addr(&addr)
108/// .expect("connect to abstract seqpacket listener");
109/// let (_server, _addr) = listener.accept_unix_addr().unwrap();
110/// ```
111///
112/// ### Xio
113///
114/// ```ignore
115/// let (mut a, b) = UnixSeqpacketConn::pair().unwrap();
116///
117/// let mut reg = XioPollRegistry::<ESS>::new().unwrap();
118/// let mut event_buf = XioPollRegistry::<ESS>::allocate_events(128.try_into().unwrap());
119///
120/// // either
121/// let a_wrapped =
122/// reg.get_registry()
123/// .en_register_wrap(a, XioEventUid::manual(1), XioChannel::INPUT)
124/// .unwrap();
125///
126/// // or
127/// reg.get_registry()
128/// .en_register&mut a, XioEventUid::manual(1), XioChannel::INPUT)
129/// .unwrap();
130///
131/// // so depending on the method, use either:
132/// a_wrapped.inner();
133///
134/// // or continue using a directly
135/// ```
136///
137/// ### Mio:
138///
139/// ```ignore
140/// let (mut a, b) = UnixSeqpacketConn::pair().unwrap();
141///
142/// let mut poll = Poll::new().expect("create mio poll");
143/// let mut events = Events::with_capacity(10);
144///
145/// poll.registry()
146/// .register(&mut a, Token(1), Interest::READABLE)
147/// .unwrap();
148/// // ...
149/// ```
150#[derive(Debug)]
151#[repr(transparent)]
152pub struct UnixSeqpacketConn
153{
154 fd: OwnedFd,
155}
156
157impl From<OwnedFd> for UnixSeqpacketConn
158{
159 fn from(ofd: OwnedFd) -> Self
160 {
161 let sa_fam = get_socket_family(&ofd).unwrap();
162 let sa_type = get_socket_type(&ofd).unwrap() & 0x00000FFF;
163
164 if sa_fam as i32 != libc::AF_UNIX || sa_type != libc::SOCK_SEQPACKET
165 {
166 panic!("assertion trap: provided FD is not AF_UNIX & SOCK_SEQPACKET, {} {}",
167 sa_fam, sa_type);
168 }
169
170 return UnixSeqpacketConn{ fd: ofd };
171 }
172}
173
174impl From<UnixSeqpacketConn> for OwnedFd
175{
176 fn from(value: UnixSeqpacketConn) -> Self
177 {
178 return value.fd;
179 }
180}
181
182impl FromRawFd for UnixSeqpacketConn
183{
184 unsafe
185 fn from_raw_fd(fd: RawFd) -> Self
186 {
187 UnixSeqpacketConn::from( unsafe { OwnedFd::from_raw_fd(fd) } )
188 }
189}
190
191impl AsRawFd for UnixSeqpacketConn
192{
193 fn as_raw_fd(&self) -> RawFd
194 {
195 self.fd.as_raw_fd()
196 }
197}
198impl IntoRawFd for UnixSeqpacketConn
199{
200 fn into_raw_fd(self) -> RawFd
201 {
202 self.fd.into_raw_fd()
203 }
204}
205
206impl AsFd for UnixSeqpacketConn
207{
208 fn as_fd(&self) -> BorrowedFd<'_>
209 {
210 self.fd.as_fd()
211 }
212}
213
214#[cfg(feature = "mio")]
215pub mod mio_conn_enabled
216{
217 use mio::{event::Source, unix::SourceFd};
218 use super::*;
219
220 impl Source for UnixSeqpacketConn
221 {
222 fn register(
223 &mut self,
224 registry: &mio::Registry,
225 token: mio::Token,
226 interests: mio::Interest,
227 ) -> io::Result<()>
228 {
229 self.set_nonblocking(true)?;
230
231 SourceFd(&self.fd.as_raw_fd()).register(registry, token, interests)
232 }
233
234 fn reregister(
235 &mut self,
236 registry: &mio::Registry,
237 token: mio::Token,
238 interests: mio::Interest,
239 ) -> io::Result<()>
240 {
241 SourceFd(&self.fd.as_raw_fd()).reregister(registry, token, interests)
242 }
243
244 fn deregister(&mut self, registry: &mio::Registry) -> io::Result<()>
245 {
246 SourceFd(&self.fd.as_raw_fd()).deregister(registry)
247 }
248 }
249}
250
251#[cfg(feature = "xio-rs")]
252pub mod xio_conn_enabled
253{
254 use xio_rs::{EsInterfaceRegistry, XioChannel, XioEventPipe, XioEventUid, XioResult, event_registry::XioRegistry};
255
256 use crate::UnixSeqpacketConn;
257
258 impl<ESSR: EsInterfaceRegistry> XioEventPipe<ESSR, Self> for UnixSeqpacketConn
259 {
260 fn connect_event_pipe(&mut self, ess: &XioRegistry<ESSR>, ev_uid: XioEventUid, channel: XioChannel) -> XioResult<()>
261 {
262 self.set_nonblocking(true)?;
263
264 ess.get_ev_sys().en_register(&self.fd, ev_uid, channel)
265 }
266
267 fn modify_event_pipe(&mut self, ess: &XioRegistry<ESSR>, ev_uid: XioEventUid, channel: XioChannel) -> XioResult<()>
268 {
269 ess.get_ev_sys().re_register(&self.fd, ev_uid, channel)
270 }
271
272 fn disconnect_event_pipe(&mut self, ess: &XioRegistry<ESSR>) -> XioResult<()>
273 {
274 ess.get_ev_sys().de_register(&self.fd)
275 }
276 }
277}
278
279impl UnixSeqpacketConn
280{
281 /// Connects to an unix seqpacket server listening at `path`.
282 ///
283 /// This is a wrapper around [`connect_unix_addr()`](#method.connect_unix_addr)
284 /// for convenience and compatibility with std.
285 pub
286 fn connect<P: AsRef<Path>>(path: P) -> Result<Self, io::Error>
287 {
288 let addr = UnixSocketAddr::from_path(&path)?;
289
290 return Self::connect_unix_addr(&addr);
291 }
292
293 /// Connects to an unix seqpacket server listening at `addr`.
294 pub
295 fn connect_unix_addr(addr: &UnixSocketAddr) -> Result<Self, io::Error>
296 {
297 let socket = Socket::<SocketSeqPkt>::new(false)?;
298 socket.set_unix_peer_addr(addr)?;
299
300 return Ok(UnixSeqpacketConn { fd: socket.into() });
301 }
302
303 /// Binds to an address before connecting to a listening seqpacet socket.
304 pub
305 fn connect_from_to_unix_addr(from: &UnixSocketAddr, to: &UnixSocketAddr) -> Result<Self, io::Error>
306 {
307 let socket = Socket::<SocketSeqPkt>::new(false)?;
308 socket.set_unix_local_addr(from)?;
309 socket.set_unix_peer_addr(to)?;
310
311 return Ok(UnixSeqpacketConn{ fd: socket.into() });
312 }
313
314 /// Creates a pair of unix-domain seqpacket conneections connected to each other.
315 ///
316 /// # Examples
317 ///
318 #[cfg_attr(not(target_vendor="apple"), doc="```")]
319 #[cfg_attr(target_vendor="apple", doc="```no_run")]
320 /// let (a, b) = uds_fork::UnixSeqpacketConn::pair().unwrap();
321 /// assert!(a.local_unix_addr().unwrap().is_unnamed());
322 /// assert!(b.local_unix_addr().unwrap().is_unnamed());
323 ///
324 /// a.send(b"hello").unwrap();
325 /// b.recv(&mut[0; 20]).unwrap();
326 /// ```
327 pub
328 fn pair() -> Result<(Self, Self), io::Error>
329 {
330 let pair = Socket::<SocketSeqPkt>::pair(false)?;
331
332 return Ok(
333 (
334 UnixSeqpacketConn { fd: pair.0.into() },
335 UnixSeqpacketConn { fd: pair.1.into() }
336 )
337 );
338 }
339
340 /// Returns the address of this side of the connection.
341 pub
342 fn local_unix_addr(&self) -> Result<UnixSocketAddr, io::Error>
343 {
344 get_unix_local_addr(&self)
345 }
346
347 /// Returns the address of the other side of the connection.
348 pub
349 fn peer_unix_addr(&self) -> Result<UnixSocketAddr, io::Error>
350 {
351 get_unix_peer_addr(&self)
352 }
353
354 /// Returns information about the process of the peer when the connection was established.
355 ///
356 /// See documentation of the returned type for details.
357 pub
358 fn initial_peer_credentials(&self) -> Result<ConnCredentials, io::Error>
359 {
360 peer_credentials(&self)
361 }
362
363 /// Returns the SELinux security context of the process that created the other
364 /// end of this connection.
365 ///
366 /// Will return an error on other operating systems than Linux or Android,
367 /// and also if running inside kubernetes.
368 /// On success the number of bytes used is returned. (like `Read`)
369 ///
370 /// The default security context is `unconfined`, without any trailing NUL.
371 /// A buffor of 50 bytes is probably always big enough.
372 pub
373 fn initial_peer_selinux_context(&self, buf: &mut[u8]) -> Result<usize, io::Error>
374 {
375 selinux_context(&self, buf)
376 }
377
378
379 /// Sends a packet to the peer.
380 pub
381 fn send(&self, packet: &[u8]) -> Result<usize, io::Error>
382 {
383 let ptr = packet.as_ptr() as *const c_void;
384 let flags = MSG_NOSIGNAL | MSG_EOR;
385 let sent = cvt_r!(unsafe { send(self.fd.as_raw_fd(), ptr, packet.len(), flags) })?;
386
387
388 return Ok(sent as usize);
389 }
390
391 /// Sends a packet to the peer.
392 pub
393 fn send_flags(&self, packet: &[u8], flags: i32) -> Result<usize, io::Error>
394 {
395 let ptr = packet.as_ptr() as *const c_void;
396 let sent = cvt_r!(unsafe { send(self.fd.as_raw_fd(), ptr, packet.len(), flags) })?;
397
398 return Ok(sent as usize);
399 }
400
401 /// Receives a packet from the peer.
402 pub
403 fn recv(&self, buffer: &mut[u8]) -> Result<usize, io::Error>
404 {
405 let ptr = buffer.as_ptr() as *mut c_void;
406 let received = cvt_r!(unsafe { recv(self.fd.as_raw_fd(), ptr, buffer.len(), MSG_NOSIGNAL) })?;
407
408 return Ok(received as usize);
409 }
410
411 /// Sends a packet assembled from multiple byte slices.
412 pub
413 fn send_vectored(&self, slices: &[IoSlice]) -> Result<usize, io::Error>
414 {
415 // Can't use writev() because we need to pass flags,
416 // and the flags accepted by pwritev2() aren't the one we need to pass.
417 send_ancillary(&self, None, MSG_EOR, slices, Vec::new(), None)
418 }
419 /// Reads a packet into multiple buffers.
420 ///
421 /// The returned `bool` indicates whether the packet was truncated due to
422 /// too short buffers.
423 pub
424 fn recv_vectored(&self, buffers: &mut[IoSliceMut]) -> Result<(usize, bool), io::Error>
425 {
426 recv_ancillary(&self, None, 0, buffers, &mut[])
427 .map(|(bytes, ancillary)| (bytes, ancillary.message_truncated()) )
428 }
429
430 /// Sends a packet with associated file descriptors.
431 pub
432 fn send_fds(&self, bytes: &[u8], fds: Vec<OwnedFd>) -> Result<usize, io::Error>
433 {
434 send_ancillary(&self, None, MSG_EOR, &[IoSlice::new(bytes)], fds, None)
435 }
436
437 /// Receives a packet and associated file descriptors. A legacy method which
438 /// was in this crate since its author added it.
439 ///
440 /// See a [Self::recv_vectored_with_ancillary] for a new stdlib approach.
441 ///
442 /// # Returns
443 ///
444 /// * 0 - amount of bytes received
445 ///
446 /// * 1 - is truncated
447 ///
448 /// * 2 - a fd buffer length
449 pub
450 fn recv_fds(&self, byte_buffer: &mut[u8], fd_buffer: &mut Vec<OwnedFd>) -> Result<(usize, bool, usize), io::Error>
451 {
452 recv_fds(&self, None, &mut[IoSliceMut::new(byte_buffer)], Some(fd_buffer))
453 }
454
455 /// A new (provided by std) parser of the ancillary data
456 ///
457 /// Unstable and extremely unsafe. Rust devs did not provide an access
458 /// to the internal reference to the buffer in [SocketAncillary], so
459 /// there is no access to the buffer and its length. For this reason a
460 /// very bad approach to overcome this is used.
461 ///
462 /// > Receives data and ancillary data from socket.
463 /// >
464 /// > On success, returns the number of bytes read, if the data was
465 /// > truncated and the address from whence the msg came.
466 ///
467 /// # Returns
468 ///
469 /// A [Result] is returned with tuple:
470 ///
471 /// * `0` - a count of bytes.
472 ///
473 /// * `1` - was msg truncated
474 ///
475 /// # Example
476 ///
477 /// ```ignore
478 /// let mut buf = [0_u8; 256];
479 /// let bufs = &mut [IoSliceMut::new(&mut buf[..])];
480 ///
481 /// let mut ancillary_buffer = [0; 128];
482 /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]);
483 ///
484 /// let (count, trunc) =
485 /// freya_side_b.recv_vectored_with_ancillary(bufs, &mut ancillary).unwrap();
486 /// ```
487 #[cfg(feature = "unsatable_preview")]
488 pub
489 fn recv_vectored_with_ancillary(
490 &self,
491 flags: i32,
492 bufs: &mut [IoSliceMut<'_>],
493 ancillary: &mut SocketAncillary<'_>,
494 ) -> Result<(usize, bool), io::Error>
495 {
496 unsafe { recv_ancillary_std(&self, flags, bufs, ancillary) }
497 .map(|(count, trunc, _)| (count, trunc))
498 }
499
500 /// A new (provided by std) parser of the ancillary data
501 ///
502 /// Unstable and extremely unsafe. Rust devs did not provide an access
503 /// to the internal reference to the buffer in [SocketAncillary], so
504 /// there is no access to the buffer and its length. For this reason a
505 /// very bad approach to overcome this is used.
506 ///
507 /// > Receives data and ancillary data providing the source of msg.
508 /// >
509 /// > On success, returns the number of bytes read, if the data was
510 /// > truncated and the address from whence the msg came.
511 ///
512 /// # Returns
513 ///
514 /// A [Result] is returned with tuple:
515 ///
516 /// * `0` - a count of bytes.
517 ///
518 /// * `1` - was msg truncated
519 ///
520 /// * `2` - a source address
521 ///
522 /// # Example
523 ///
524 /// ```ignore
525 /// let mut buf = [0_u8; 256];
526 /// let bufs = &mut [IoSliceMut::new(&mut buf[..])];
527 ///
528 /// let mut ancillary_buffer = [0; 128];
529 /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]);
530 ///
531 /// let (count, trunc, from) =
532 /// freya_side_b.recv_vectored_with_ancillary(bufs, &mut ancillary).unwrap();
533 /// ```
534 #[cfg(feature = "unsatable_preview")]
535 pub
536 fn recv_vectored_with_ancillary_from(
537 &self,
538 flags: i32,
539 bufs: &mut [IoSliceMut<'_>],
540 ancillary: &mut SocketAncillary<'_>,
541 ) -> Result<(usize, bool, UnixSocketAddr), io::Error>
542 {
543 unsafe { recv_ancillary_std(&self, flags, bufs, ancillary) }
544 }
545
546 /// A new (provided by std) parser of the ancillary data.
547 ///
548 /// Rust #![feature(unix_socket_ancillary_data)]
549 ///
550 /// Unstable and extremely unsafe. Rust devs did not provide an access
551 /// to the internal reference to the buffer in [SocketAncillary], so
552 /// there is no access to the buffer and its length. For this reason a
553 /// very bad approach to overcome this is used.
554 ///
555 /// > Sends data and ancillary data on the current socket.
556 /// >
557 /// > On success, returns the number of bytes written.
558 ///
559 /// Crate: feature = unsatable_preview
560 ///
561 /// # Arguments
562 ///
563 /// * `flags` - a flags which are passed to [libc::recvmsg].
564 ///
565 /// * `bufs` - an [IoSlice] buffers.
566 ///
567 /// * `ancillary` - packed ancillary data
568 ///
569 /// # Example
570 ///
571 /// ```ignore
572 /// let buf0 = b"Here I come";
573 /// let mut ancillary_buffer = [0; 128];
574 /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]);
575 ///
576 /// let fds = [OwnedFd::from(a).into_raw_fd(), OwnedFd::from(b).into_raw_fd(), OwnedFd::from(aa).into_raw_fd()];
577 ///
578 /// ancillary.add_fds(&fds[..]);
579 ///
580 /// freya_side_a.send_vectored_with_ancillary(&[IoSlice::new(buf0.as_slice())], &mut ancillary)
581 /// .expect("send stdin, stdout and stderr");
582 ///
583 /// ```
584 #[cfg(feature = "unsatable_preview")]
585 pub
586 fn send_vectored_with_ancillary(
587 &self,
588 flags: i32,
589 bufs: &[IoSlice<'_>],
590 ancillary: &mut SocketAncillary<'_>,
591 ) -> io::Result<usize>
592 {
593 unsafe { send_ancillary_std(&self, None, flags, bufs, ancillary) }
594 }
595
596 /// A new (provided by std) parser of the ancillary data.
597 ///
598 /// Rust #![feature(unix_socket_ancillary_data)]
599 ///
600 /// Unstable and extremely unsafe. Rust devs did not provide an access
601 /// to the internal reference to the buffer in [SocketAncillary], so
602 /// there is no access to the buffer and its length. For this reason a
603 /// very bad approach to overcome this is used.
604 ///
605 /// > Sends data and ancillary data on the socket to the specified address.
606 /// >
607 /// > On success, returns the number of bytes written.
608 ///
609 /// Crate: feature = unsatable_preview
610 ///
611 /// # Arguments
612 ///
613 /// * `flags` - a flags which are passed to [libc::recvmsg].
614 ///
615 /// * `to` - a destination.
616 ///
617 /// * `bufs` - an [IoSlice] buffers.
618 ///
619 /// * `ancillary` - packed ancillary data
620 ///
621 /// # Example
622 ///
623 /// ```ignore
624 /// let buf0 = b"Here I come";
625 /// let mut ancillary_buffer = [0; 128];
626 /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]);
627 ///
628 /// let fds =
629 /// [OwnedFd::from(a).into_raw_fd(), OwnedFd::from(b).into_raw_fd(), OwnedFd::from(aa).into_raw_fd()];
630 ///
631 /// ancillary.add_fds(&fds[..]);
632 ///
633 /// let dst = UnixSocketAddr::from_abstract("@test");
634 ///
635 /// freya_side_a
636 /// .send_vectored_with_ancillary_to(0, &dst, &[IoSlice::new(buf0.as_slice())], &mut ancillary)
637 /// .expect("send stdin, stdout and stderr");
638 ///
639 /// ```
640 #[cfg(feature = "unsatable_preview")]
641 pub
642 fn send_vectored_with_ancillary_to(
643 &self,
644 flags: i32,
645 to: &UnixSocketAddr,
646 bufs: &[IoSlice<'_>],
647 ancillary: &mut SocketAncillary<'_>,
648 ) -> io::Result<usize>
649 {
650 unsafe { send_ancillary_std(&self, Some(to), flags, bufs, ancillary) }
651 }
652
653 /// Receives a packet without removing it from the incoming queue.
654 ///
655 /// # Examples
656 ///
657 #[cfg_attr(not(target_vendor="apple"), doc="```")]
658 #[cfg_attr(target_vendor="apple", doc="```no_run")]
659 /// let (a, b) = uds_fork::UnixSeqpacketConn::pair().unwrap();
660 /// a.send(b"hello").unwrap();
661 /// let mut buf = [0u8; 10];
662 /// assert_eq!(b.peek(&mut buf[..1]).unwrap(), 1);
663 /// assert_eq!(&buf[..2], &[b'h', 0]);
664 /// assert_eq!(b.peek(&mut buf).unwrap(), 5);
665 /// assert_eq!(&buf[..5], b"hello");
666 /// assert_eq!(b.recv(&mut buf).unwrap(), 5);
667 /// assert_eq!(&buf[..5], b"hello");
668 /// ```
669 pub
670 fn peek(&self, buffer: &mut[u8]) -> Result<usize, io::Error>
671 {
672 let ptr = buffer.as_ptr() as *mut c_void;
673 let flags = MSG_NOSIGNAL | MSG_PEEK;
674 let received = cvt_r!(unsafe { recv(self.fd.as_raw_fd(), ptr, buffer.len(), flags) })?;
675
676 return Ok(received as usize);
677 }
678
679 /// Receives a packet without removing it from the incoming queue.
680 ///
681 /// The returned `bool` indicates whether the packet was truncated due to
682 /// the combined buffers being too small.
683 pub
684 fn peek_vectored(&self, buffers: &mut[IoSliceMut]) -> Result<(usize, bool), io::Error>
685 {
686 recv_ancillary(&self, None, MSG_PEEK, buffers, &mut[])
687 .map(|(bytes, ancillary)| (bytes, ancillary.message_truncated()) )
688 }
689
690 /// Returns the value of the `SO_ERROR` option.
691 ///
692 /// This might only provide errors generated from nonblocking `connect()`s,
693 /// which this library doesn't support. It is therefore unlikely to be
694 /// useful, but is provided for parity with stream counterpart in std.
695 ///
696 /// # Examples
697 ///
698 #[cfg_attr(not(target_vendor="apple"), doc="```")]
699 #[cfg_attr(target_vendor="apple", doc="```no_run")]
700 /// let (a, b) = uds_fork::UnixSeqpacketConn::pair().unwrap();
701 /// drop(b);
702 ///
703 /// assert!(a.send(b"anyone there?").is_err());
704 /// assert!(a.take_error().unwrap().is_none());
705 /// ```
706 pub
707 fn take_error(&self) -> Result<Option<io::Error>, io::Error>
708 {
709 take_error(&self)
710 }
711
712
713 /// Creates a new file descriptor also pointing to this side of this connection.
714 ///
715 /// # Examples
716 ///
717 /// Both new and old can send and receive, and share queues:
718 ///
719 #[cfg_attr(not(target_vendor="apple"), doc="```")]
720 #[cfg_attr(target_vendor="apple", doc="```no_run")]
721 /// let (a1, b) = uds_fork::nonblocking::UnixSeqpacketConn::pair().unwrap();
722 /// let a2 = a1.try_clone().unwrap();
723 ///
724 /// a1.send(b"first").unwrap();
725 /// a2.send(b"second").unwrap();
726 ///
727 /// let mut buf = [0u8; 20];
728 /// let len = b.recv(&mut buf).unwrap();
729 /// assert_eq!(&buf[..len], b"first");
730 /// b.send(b"hello first").unwrap();
731 /// let len = b.recv(&mut buf).unwrap();
732 /// assert_eq!(&buf[..len], b"second");
733 /// b.send(b"hello second").unwrap();
734 ///
735 /// let len = a2.recv(&mut buf).unwrap();
736 /// assert_eq!(&buf[..len], b"hello first");
737 /// let len = a1.recv(&mut buf).unwrap();
738 /// assert_eq!(&buf[..len], b"hello second");
739 /// ```
740 ///
741 /// Clone can still be used after the first one has been closed:
742 ///
743 #[cfg_attr(not(target_vendor="apple"), doc="```")]
744 #[cfg_attr(target_vendor="apple", doc="```no_run")]
745 /// let (a, b1) = uds_fork::nonblocking::UnixSeqpacketConn::pair().unwrap();
746 /// a.send(b"hello").unwrap();
747 ///
748 /// let b2 = b1.try_clone().unwrap();
749 /// drop(b1);
750 /// assert_eq!(b2.recv(&mut[0; 10]).unwrap(), "hello".len());
751 /// ```
752 pub
753 fn try_clone(&self) -> Result<Self, io::Error>
754 {
755 let cloned = Socket::<SocketSeqPkt>::try_clone_from(self)?;
756
757 return Ok(UnixSeqpacketConn { fd: cloned.into() });
758 }
759
760 /// Sets the read timeout to the duration specified.
761 ///
762 /// If the value specified is `None`, then `recv()` and its variants will
763 /// block indefinitely.
764 /// An error is returned if the duration is zero.
765 ///
766 /// The duration is rounded to microsecond precission.
767 /// Currently it's rounded down except if that would make it all zero.
768 ///
769 /// # Operating System Support
770 ///
771 /// On Illumos (and pressumably also Solaris) timeouts appears not to work
772 /// for unix domain sockets.
773 ///
774 /// # Examples
775 ///
776 #[cfg_attr(not(any(target_vendor="apple", target_os="illumos", target_os="solaris")), doc="```")]
777 #[cfg_attr(any(target_vendor="apple", target_os="illumos", target_os="solaris"), doc="```no_run")]
778 /// use std::io::ErrorKind;
779 /// use std::time::Duration;
780 /// use uds_fork::UnixSeqpacketConn;
781 ///
782 /// let (a, b) = UnixSeqpacketConn::pair().unwrap();
783 /// a.set_read_timeout(Some(Duration::new(0, 2_000_000))).unwrap();
784 /// let error = a.recv(&mut[0; 1024]).unwrap_err();
785 /// assert_eq!(error.kind(), ErrorKind::WouldBlock);
786 /// ```
787 pub
788 fn set_read_timeout(&self, timeout: Option<Duration>) -> Result<(), io::Error>
789 {
790 set_timeout(self.fd.as_fd(), TimeoutDirection::Read, timeout)
791 }
792
793 /// Returns the read timeout of this socket.
794 ///
795 /// `None` is returned if there is no timeout.
796 ///
797 /// Note that subsecond parts might have been be rounded by the OS
798 /// (in addition to the rounding to microsecond in `set_read_timeout()`).
799 ///
800 /// # Examples
801 ///
802 #[cfg_attr(not(any(target_vendor="apple", target_os="illumos", target_os="solaris")), doc="```")]
803 #[cfg_attr(any(target_vendor="apple", target_os="illumos", target_os="solaris"), doc="```no_run")]
804 /// use uds_fork::UnixSeqpacketConn;
805 /// use std::time::Duration;
806 ///
807 /// let timeout = Some(Duration::new(2, 0));
808 /// let conn = UnixSeqpacketConn::pair().unwrap().0;
809 /// conn.set_read_timeout(timeout).unwrap();
810 /// assert_eq!(conn.read_timeout().unwrap(), timeout);
811 /// ```
812 pub
813 fn read_timeout(&self) -> Result<Option<Duration>, io::Error>
814 {
815 get_timeout(self.fd.as_fd(), TimeoutDirection::Read)
816 }
817
818 /// Sets the write timeout to the duration specified.
819 ///
820 /// If the value specified is `None`, then `send()` and its variants will
821 /// block indefinitely.
822 /// An error is returned if the duration is zero.
823 ///
824 /// # Operating System Support
825 ///
826 /// On Illumos (and pressumably also Solaris) timeouts appears not to work
827 /// for unix domain sockets.
828 ///
829 /// # Examples
830 ///
831 #[cfg_attr(not(any(target_vendor="apple", target_os="illumos", target_os="solaris")), doc="```")]
832 #[cfg_attr(any(target_vendor="apple", target_os="illumos", target_os="solaris"), doc="```no_run")]
833 /// # use std::io::ErrorKind;
834 /// # use std::time::Duration;
835 /// # use uds_fork::UnixSeqpacketConn;
836 /// #
837 /// let (conn, _other) = UnixSeqpacketConn::pair().unwrap();
838 /// conn.set_write_timeout(Some(Duration::new(0, 500 * 1000))).unwrap();
839 /// loop {
840 /// if let Err(e) = conn.send(&[0; 1000]) {
841 /// assert_eq!(e.kind(), ErrorKind::WouldBlock, "{}", e);
842 /// break
843 /// }
844 /// }
845 /// ```
846 pub
847 fn set_write_timeout(&self, timeout: Option<Duration>)-> Result<(), io::Error>
848 {
849 set_timeout(self.fd.as_fd(), TimeoutDirection::Write, timeout)
850 }
851
852 /// Returns the write timeout of this socket.
853 ///
854 /// `None` is returned if there is no timeout.
855 ///
856 /// # Examples
857 ///
858 #[cfg_attr(not(target_vendor="apple"), doc="```")]
859 #[cfg_attr(target_vendor="apple", doc="```no_run")]
860 /// let conn = uds_fork::UnixSeqpacketConn::pair().unwrap().0;
861 /// assert!(conn.write_timeout().unwrap().is_none());
862 /// ```
863 pub
864 fn write_timeout(&self) -> Result<Option<Duration>, io::Error>
865 {
866 get_timeout(self.fd.as_fd(), TimeoutDirection::Write)
867 }
868
869 /// Enables or disables nonblocking mode.
870 ///
871 /// Consider using the nonblocking variant of this type instead.
872 /// This method mainly exists for feature parity with std's `UnixStream`.
873 ///
874 /// # Examples
875 ///
876 /// Trying to receive when there are no packets waiting:
877 ///
878 #[cfg_attr(not(target_vendor="apple"), doc="```")]
879 #[cfg_attr(target_vendor="apple", doc="```no_run")]
880 /// # use std::io::ErrorKind;
881 /// # use uds_fork::UnixSeqpacketConn;
882 /// let (a, b) = UnixSeqpacketConn::pair().expect("create seqpacket pair");
883 /// a.set_nonblocking(true).unwrap();
884 /// assert_eq!(a.recv(&mut[0; 20]).unwrap_err().kind(), ErrorKind::WouldBlock);
885 /// ```
886 ///
887 /// Trying to send when the OS buffer for the connection is full:
888 ///
889 #[cfg_attr(not(target_vendor="apple"), doc="```")]
890 #[cfg_attr(target_vendor="apple", doc="```no_run")]
891 /// # use std::io::ErrorKind;
892 /// # use uds_fork::UnixSeqpacketConn;
893 /// let (a, b) = UnixSeqpacketConn::pair().expect("create seqpacket pair");
894 /// a.set_nonblocking(true).unwrap();
895 /// loop {
896 /// if let Err(error) = a.send(&[b'#'; 1000]) {
897 /// assert_eq!(error.kind(), ErrorKind::WouldBlock);
898 /// break;
899 /// }
900 /// }
901 /// ```
902 pub
903 fn set_nonblocking(&self, nonblocking: bool) -> Result<(), io::Error>
904 {
905 set_nonblocking(&self, nonblocking)
906 }
907
908 /// Shuts down the read, write, or both halves of this connection.
909 pub
910 fn shutdown(&self, how: Shutdown) -> io::Result<()>
911 {
912 let how =
913 match how
914 {
915 Shutdown::Read => libc::SHUT_RD,
916 Shutdown::Write => libc::SHUT_WR,
917 Shutdown::Both => libc::SHUT_RDWR,
918 };
919
920 unsafe { cvt!(libc::shutdown(self.as_raw_fd(), how)) }?;
921
922 return Ok(());
923 }
924
925 fn read_string(&self, buf: &mut String) -> io::Result<usize>
926 {
927 let mut read_size: u32 = 0;
928
929 let _ =
930 cvt!(unsafe { libc::ioctl(self.fd.as_raw_fd(), libc::FIONREAD, &mut read_size) })?;
931
932 let mut byte_buf = vec![0_u8; read_size as usize];
933
934 let _ = self.recv(&mut byte_buf)?;
935
936 let str_slice =
937 str::from_utf8(&byte_buf)
938 .map_err(|e|
939 io::Error::new(ErrorKind::Other, e)
940 )?;
941
942 buf.push_str(str_slice);
943
944 return Ok(byte_buf.len());
945 }
946}
947
948impl io::Read for UnixSeqpacketConn
949{
950 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize>
951 {
952 self.recv(buf)
953 }
954
955 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize>
956 {
957 self.recv_vectored(bufs).map(|(n, _)| n)
958 }
959
960 fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize>
961 {
962 self.read_string(buf)
963 }
964}
965
966impl<'a> io::Read for &'a UnixSeqpacketConn
967{
968 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize>
969 {
970 self.recv(buf)
971 }
972
973 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize>
974 {
975 self.recv_vectored(bufs).map(|(n, _)| n)
976 }
977
978 fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize>
979 {
980 self.read_string(buf)
981 }
982}
983
984impl io::Write for UnixSeqpacketConn
985{
986 fn write(&mut self, buf: &[u8]) -> io::Result<usize>
987 {
988 self.send(buf)
989 }
990
991 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize>
992 {
993 self.send_vectored(bufs)
994 }
995
996 fn flush(&mut self) -> io::Result<()>
997 {
998 return Ok(());
999 }
1000}
1001
1002/// An unix domain listener for sequential packet connections.
1003///
1004/// See [`UnixSeqpacketConn`](struct.UnixSeqpacketConn.html) for a description
1005/// of this type of connection.
1006///
1007/// # Registering with Xio (xio-rs) a feature = "xio-rs"
1008///
1009/// A `XioEventPipe` is implemented on this function. During initial registration
1010/// an attempt set `nonblocking` mode is performed during initial registration.
1011///
1012/// See examples below.
1013///
1014/// # Registering with Mio (mio) a feature = "mio"
1015///
1016/// A `Source` is implemented on the instance.During initial registration
1017/// an attempt set `nonblocking` mode is performed during initial registration.
1018///
1019/// # Examples
1020///
1021#[cfg_attr(not(target_vendor="apple"), doc="```")]
1022#[cfg_attr(target_vendor="apple", doc="```no_run")]
1023/// use tempfile::TempDir;
1024///
1025/// let dir = tempfile::tempdir().unwrap();
1026/// let mut file_path = dir.path().join("seqpacket_listener.socket");
1027///
1028/// let listener = uds_fork::UnixSeqpacketListener::bind(&file_path)
1029/// .expect("Create seqpacket listener");
1030/// let _client = uds_fork::UnixSeqpacketConn::connect(&file_path).unwrap();
1031/// let (conn, _addr) = listener.accept_unix_addr().unwrap();
1032/// conn.send(b"Welcome").unwrap();
1033/// ```
1034///
1035/// ### Xio
1036///
1037/// ```ignore
1038/// let listener = uds_fork::UnixSeqpacketListener::bind(file_path).unwrap();
1039///
1040/// let mut reg = XioPollRegistry::<ESS>::new().unwrap();
1041/// let mut event_buf = XioPollRegistry::<ESS>::allocate_events(128.try_into().unwrap());
1042///
1043/// // either
1044/// let a_wrapped =
1045/// reg.get_registry()
1046/// .en_register_wrap(listener, XioEventUid::manual(1), XioChannel::INPUT)
1047/// .unwrap();
1048///
1049/// // or
1050/// reg.get_registry()
1051/// .en_register&mut listener, XioEventUid::manual(1), XioChannel::INPUT)
1052/// .unwrap();
1053///
1054/// // so depending on the method, use either:
1055/// a_wrapped.inner();
1056///
1057/// // or continue using a directly
1058/// ```
1059///
1060/// ### Mio:
1061///
1062/// ```ignore
1063/// let listener = uds_fork::UnixSeqpacketListener::bind(file_path).unwrap();
1064///
1065/// let mut poll = Poll::new().expect("create mio poll");
1066/// let mut events = Events::with_capacity(10);
1067///
1068/// poll.registry()
1069/// .register(&mut listener, Token(1), Interest::READABLE)
1070/// .unwrap();
1071/// // ...
1072/// ```
1073#[derive(Debug)]
1074#[repr(transparent)]
1075pub struct UnixSeqpacketListener
1076{
1077 fd: OwnedFd
1078}
1079
1080
1081impl From<OwnedFd> for UnixSeqpacketListener
1082{
1083 fn from(ofd: OwnedFd) -> Self
1084 {
1085 let sa_fam = get_socket_family(&ofd).unwrap();
1086 let sa_type = get_socket_type(&ofd).unwrap() & 0x00000FFF;
1087
1088 if sa_fam as i32 != libc::AF_UNIX || sa_type != libc::SOCK_SEQPACKET
1089 {
1090 panic!("assertion trap: provided FD is not AF_UNIX & SOCK_SEQPACKET, {} {}",
1091 sa_fam, sa_type);
1092 }
1093
1094 return UnixSeqpacketListener{ fd: ofd };
1095 }
1096}
1097
1098impl From<UnixSeqpacketListener> for OwnedFd
1099{
1100 fn from(value: UnixSeqpacketListener) -> Self
1101 {
1102 return value.fd;
1103 }
1104}
1105
1106impl FromRawFd for UnixSeqpacketListener
1107{
1108 unsafe
1109 fn from_raw_fd(fd: RawFd) -> Self
1110 {
1111 UnixSeqpacketListener::from( unsafe { OwnedFd::from_raw_fd(fd) } )
1112 }
1113}
1114
1115impl AsRawFd for UnixSeqpacketListener
1116{
1117 fn as_raw_fd(&self) -> RawFd
1118 {
1119 self.fd.as_raw_fd()
1120 }
1121}
1122
1123impl IntoRawFd for UnixSeqpacketListener
1124{
1125 fn into_raw_fd(self) -> RawFd
1126 {
1127 self.fd.into_raw_fd()
1128 }
1129}
1130
1131impl AsFd for UnixSeqpacketListener
1132{
1133 fn as_fd(&self) -> BorrowedFd<'_>
1134 {
1135 self.fd.as_fd()
1136 }
1137}
1138
1139#[cfg(feature = "mio")]
1140pub mod mio_listener_enabled
1141{
1142 use std::{io, os::fd::AsRawFd};
1143
1144 use mio::{event::Source, unix::SourceFd};
1145 use crate::UnixSeqpacketListener;
1146
1147 impl Source for UnixSeqpacketListener
1148 {
1149 fn register(
1150 &mut self,
1151 registry: &mio::Registry,
1152 token: mio::Token,
1153 interests: mio::Interest,
1154 ) -> io::Result<()>
1155 {
1156 self.set_nonblocking(true)?;
1157
1158 SourceFd(&self.fd.as_raw_fd()).register(registry, token, interests)
1159 }
1160
1161 fn reregister(
1162 &mut self,
1163 registry: &mio::Registry,
1164 token: mio::Token,
1165 interests: mio::Interest,
1166 ) -> io::Result<()>
1167 {
1168 SourceFd(&self.fd.as_raw_fd()).reregister(registry, token, interests)
1169 }
1170
1171 fn deregister(&mut self, registry: &mio::Registry) -> io::Result<()>
1172 {
1173 SourceFd(&self.fd.as_raw_fd()).deregister(registry)
1174 }
1175 }
1176}
1177
1178#[cfg(feature = "xio-rs")]
1179pub mod xio_listener_enabled
1180{
1181 use xio_rs::{EsInterfaceRegistry, XioChannel, XioEventPipe, XioEventUid, XioResult, event_registry::XioRegistry};
1182
1183 use crate::UnixSeqpacketListener;
1184
1185 impl<ESSR: EsInterfaceRegistry> XioEventPipe<ESSR, Self> for UnixSeqpacketListener
1186 {
1187 fn connect_event_pipe(&mut self, ess: &XioRegistry<ESSR>, ev_uid: XioEventUid, channel: XioChannel) -> XioResult<()>
1188 {
1189 self.set_nonblocking(true)?;
1190
1191 ess.get_ev_sys().en_register(&self.fd, ev_uid, channel)
1192 }
1193
1194 fn modify_event_pipe(&mut self, ess: &XioRegistry<ESSR>, ev_uid: XioEventUid, channel: XioChannel) -> XioResult<()>
1195 {
1196 ess.get_ev_sys().re_register(&self.fd, ev_uid, channel)
1197 }
1198
1199 fn disconnect_event_pipe(&mut self, ess: &XioRegistry<ESSR>) -> XioResult<()>
1200 {
1201 ess.get_ev_sys().de_register(&self.fd)
1202 }
1203 }
1204}
1205
1206impl UnixSeqpacketListener
1207{
1208 /// Creates a socket that listens for seqpacket connections on the specified socket file.
1209 pub
1210 fn bind<P: AsRef<Path>>(path: P) -> Result<Self, io::Error>
1211 {
1212 let addr = UnixSocketAddr::from_path(path.as_ref())?;
1213
1214 return Self::bind_unix_addr(&addr);
1215 }
1216
1217 /// Creates a socket that listens for seqpacket connections on the specified address.
1218 pub
1219 fn bind_unix_addr(addr: &UnixSocketAddr) -> Result<Self, io::Error>
1220 {
1221 let socket = Socket::<SocketSeqPkt>::new(false)?;
1222
1223 socket.set_unix_local_addr(addr)?;
1224 socket.start_listening()?;
1225
1226 return Ok(UnixSeqpacketListener { fd: socket.into() });
1227 }
1228
1229 /// Returns the address the socket is listening on.
1230 pub
1231 fn local_unix_addr(&self) -> Result<UnixSocketAddr, io::Error>
1232 {
1233 get_unix_local_addr(&self)
1234 }
1235
1236 /// Accepts a new incoming connection to this listener.
1237 ///
1238 /// Rustdocs:
1239 /// > This function will block the calling thread until a new Unix connection
1240 /// > is established. When established, the corresponding [`UnixSeqpacketConn`] and
1241 /// > the remote peer's address will be returned.
1242 ///
1243 /// [`UnixSeqpacketConn`]: UnixSeqpacketConn
1244 ///
1245 /// # Examples
1246 ///
1247 /// ```no_run
1248 /// use uds_fork::UnixSeqpacketListener;
1249 ///
1250 /// fn main() -> std::io::Result<()>
1251 /// {
1252 /// let listener = UnixSeqpacketListener::bind("/path/to/the/socket")?;
1253 ///
1254 /// match listener.accept()
1255 /// {
1256 /// Ok((socket, addr)) =>
1257 /// println!("Got a client: {addr:?}"),
1258 /// Err(e) =>
1259 /// println!("accept function failed: {e:?}"),
1260 /// }
1261 ///
1262 /// return Ok(());
1263 /// }
1264 /// ```
1265 #[inline]
1266 pub
1267 fn accept(&self)-> Result<(UnixSeqpacketConn, UnixSocketAddr), io::Error>
1268 {
1269 self.accept_unix_addr()
1270 }
1271
1272 /// Accepts a new incoming connection to this listener.
1273 ///
1274 /// See [Self::accept].
1275 pub
1276 fn accept_unix_addr(&self)-> Result<(UnixSeqpacketConn, UnixSocketAddr), io::Error>
1277 {
1278 let (socket, addr) = Socket::<SocketSeqPkt>::accept_from(&self, false)?;
1279 let conn = UnixSeqpacketConn { fd: socket.into() };
1280
1281 return Ok((conn, addr));
1282 }
1283
1284 /// Returns the value of the `SO_ERROR` option.
1285 ///
1286 /// This might never produce any errors for listeners. It is therefore
1287 /// unlikely to be useful, but is provided for parity with
1288 /// `std::unix::net::UnixListener`.
1289 pub
1290 fn take_error(&self) -> Result<Option<io::Error>, io::Error>
1291 {
1292 take_error(&self)
1293 }
1294
1295 /// Creates a new file descriptor listening for the same connections.
1296 pub
1297 fn try_clone(&self) -> Result<Self, io::Error>
1298 {
1299 let cloned = Socket::<SocketSeqPkt>::try_clone_from(&self)?;
1300
1301 return Ok(UnixSeqpacketListener { fd: cloned.into() });
1302 }
1303
1304 /// Sets a maximum duration to wait in a single `accept()` on this socket.
1305 ///
1306 /// `None` disables a previously set timeout.
1307 /// An error is returned if the duration is zero.
1308 ///
1309 /// # Operating System Support
1310 ///
1311 /// Only Linux appers to apply timeouts to `accept()`.
1312 /// On macOS, FreeBSD and NetBSD, timeouts are silently ignored.
1313 /// On Illumos setting timeouts for all unix domain sockets silently fails.
1314 ///
1315 /// On OSes where timeouts are known to not work, this function will
1316 /// return an error even if setting the timeout didn't fail.
1317 ///
1318 /// # Examples
1319 ///
1320 #[cfg_attr(any(target_os="linux", target_os="android"), doc="```")]
1321 #[cfg_attr(not(any(target_os="linux", target_os="android")), doc="```no_run")]
1322 /// # use uds_fork::{UnixSeqpacketListener, UnixSocketAddr};
1323 /// # use std::io::ErrorKind;
1324 /// # use std::time::Duration;
1325 /// #
1326 /// # let addr = UnixSocketAddr::new("@set_timeout").unwrap();
1327 /// let listener = UnixSeqpacketListener::bind_unix_addr(&addr).unwrap();
1328 /// listener.set_timeout(Some(Duration::new(0, 200_000_000))).unwrap();
1329 /// let err = listener.accept_unix_addr().unwrap_err();
1330 /// assert_eq!(err.kind(), ErrorKind::WouldBlock);
1331 /// ```
1332 pub
1333 fn set_timeout(&self, timeout: Option<Duration>) -> Result<(), io::Error>
1334 {
1335 let res = set_timeout(&self, TimeoutDirection::Read, timeout);
1336
1337 #[cfg(any(
1338 target_vendor="apple", target_os="freebsd",
1339 target_os="netbsd",
1340 target_os="illumos", target_os="solaris",
1341 ))]
1342 {
1343 if res.is_ok() == true && timeout.is_some() == true
1344 {
1345 return Err(
1346 io::Error::new(
1347 ErrorKind::InvalidInput,
1348 "listener timeouts are not supported on this OS"
1349 )
1350 );
1351 }
1352 }
1353
1354 return res;
1355 }
1356
1357 /// Returns the timeout for `accept()` on this socket.
1358 ///
1359 /// `None` is returned if there is no timeout.
1360 ///
1361 /// Even if a timeout has is set, it is ignored by `accept()` on
1362 /// most operating systems except Linux.
1363 ///
1364 /// # Examples
1365 ///
1366 #[cfg_attr(any(target_os="linux", target_os="android"), doc="```")]
1367 #[cfg_attr(not(any(target_os="linux", target_os="android")), doc="```no_run")]
1368 /// # use uds_fork::{UnixSeqpacketListener, UnixSocketAddr};
1369 /// # use std::time::Duration;
1370 /// #
1371 /// # let addr = UnixSocketAddr::new("@timeout").unwrap();
1372 /// let listener = UnixSeqpacketListener::bind_unix_addr(&addr).unwrap();
1373 /// assert_eq!(listener.timeout().unwrap(), None);
1374 /// let timeout = Some(Duration::new(2, 0));
1375 /// listener.set_timeout(timeout).unwrap();
1376 /// assert_eq!(listener.timeout().unwrap(), timeout);
1377 /// ```
1378 pub
1379 fn timeout(&self) -> Result<Option<Duration>, io::Error>
1380 {
1381 get_timeout(&self, TimeoutDirection::Read)
1382 }
1383
1384 /// Enables or disables nonblocking-ness of [`accept_unix_addr()`](#method.accept_unix addr).
1385 ///
1386 /// The returned connnections will still be in blocking mode regardsless.
1387 ///
1388 /// Consider using the nonblocking variant of this type instead;
1389 /// this method mostly exists for feature parity with std's `UnixListener`.
1390 ///
1391 /// # Examples
1392 ///
1393 #[cfg_attr(not(target_vendor="apple"), doc="```")]
1394 #[cfg_attr(target_vendor="apple", doc="```no_run")]
1395 /// # use std::io::ErrorKind;
1396 /// # use uds_fork::{UnixSocketAddr, UnixSeqpacketListener};
1397 /// use tempfile::TempDir;
1398 ///
1399 /// let dir = tempfile::tempdir().unwrap();
1400 /// let mut file_path = dir.path().join("nonblocking_seqpacket_listener1.socket");
1401 ///
1402 /// let addr = UnixSocketAddr::from_path(&file_path).unwrap();
1403 /// let listener = UnixSeqpacketListener::bind_unix_addr(&addr).expect("create listener");
1404 /// listener.set_nonblocking(true).expect("enable noblocking mode");
1405 /// assert_eq!(listener.accept_unix_addr().unwrap_err().kind(), ErrorKind::WouldBlock);
1406 /// ```
1407 pub
1408 fn set_nonblocking(&self, nonblocking: bool) -> Result<(), io::Error>
1409 {
1410 set_nonblocking(&self, nonblocking)
1411 }
1412
1413 /// Returns an iterator over incoming connections.
1414 ///
1415 /// Rustdoc:
1416 /// > The iterator will never return [`None`] and will also not yield the
1417 /// > peer's [`UnixSocketAddr`] structure.
1418 ///
1419 /// ```no_run
1420 /// use std::thread;
1421 /// use uds_fork::{UnixSeqpacketConn, UnixSeqpacketListener};
1422 ///
1423 /// fn handle_client(stream: UnixSeqpacketConn)
1424 /// {
1425 /// // ...
1426 /// }
1427 ///
1428 /// fn main() -> std::io::Result<()>
1429 /// {
1430 /// let listener = UnixSeqpacketListener::bind("/path/to/the/socket")?;
1431 ///
1432 /// for stream in listener.incoming()
1433 /// {
1434 /// match stream
1435 /// {
1436 /// Ok(stream) =>
1437 /// {
1438 /// thread::spawn(|| handle_client(stream));
1439 /// },
1440 /// Err(err) =>
1441 /// {
1442 /// break;
1443 /// }
1444 /// }
1445 /// }
1446 ///
1447 /// return Ok(());
1448 /// }
1449 /// ```
1450 pub
1451 fn incoming(&self) -> Incoming<'_>
1452 {
1453 Incoming { listener: self }
1454 }
1455}
1456
1457/// A rust std API.
1458///
1459/// From Rustdocs:
1460/// > An iterator over incoming connections to a [`UnixListener`].
1461/// >
1462/// > It will never return [`None`].
1463///
1464/// # Examples
1465///
1466/// ```no_run
1467/// use std::thread;
1468/// use uds_fork::{UnixSeqpacketConn, UnixSeqpacketListener};
1469///
1470/// fn handle_client(stream: UnixSeqpacketConn) {
1471/// // ...
1472/// }
1473///
1474/// fn main() -> std::io::Result<()>
1475/// {
1476/// let listener = UnixSeqpacketListener::bind("/path/to/the/socket")?;
1477///
1478/// for stream in listener.incoming()
1479/// {
1480/// match stream
1481/// {
1482/// Ok(stream) =>
1483/// {
1484/// thread::spawn(|| handle_client(stream));
1485/// }
1486/// Err(err) =>
1487/// {
1488/// break;
1489/// }
1490/// }
1491/// }
1492/// return Ok(());
1493/// }
1494/// ```
1495#[derive(Debug)]
1496pub struct Incoming<'a>
1497{
1498 listener: &'a UnixSeqpacketListener,
1499}
1500
1501impl<'a> Iterator for Incoming<'a>
1502{
1503 type Item = io::Result<UnixSeqpacketConn>;
1504
1505 fn next(&mut self) -> Option<io::Result<UnixSeqpacketConn>>
1506 {
1507 Some(self.listener.accept().map(|s| s.0))
1508 }
1509
1510 fn size_hint(&self) -> (usize, Option<usize>)
1511 {
1512 (usize::MAX, None)
1513 }
1514}
1515
1516impl<'a> IntoIterator for &'a UnixSeqpacketListener
1517{
1518 type Item = io::Result<UnixSeqpacketConn>;
1519 type IntoIter = Incoming<'a>;
1520
1521 fn into_iter(self) -> Incoming<'a>
1522 {
1523 self.incoming()
1524 }
1525}
1526
1527
1528
1529/// A non-blocking unix domain sequential-packet connection.
1530///
1531/// Differs from [`uds_fork::UnixSeqpacketConn`](../struct.UnixSeqpacketConn.html)
1532/// in that all operations that send or receive data will return an `Error` of
1533/// kind `ErrorKind::WouldBlock` instead of blocking.
1534/// This is done by creating the socket as non-blocking, and not by passing
1535/// `MSG_DONTWAIT`. If creating this type from a raw file descriptor, ensure
1536/// the fd is set to nonblocking before using it through this type.
1537///
1538/// # Registering with Xio (xio-rs) a feature = "xio-rs"
1539///
1540/// A `XioEventPipe` is implemented on this function. See [UnixSeqpacketConn]
1541/// for an examples.
1542///
1543/// See examples below.
1544///
1545/// # Registering with Mio (mio) a feature = "mio"
1546///
1547/// A `Source` is implemented on the instance. See [UnixSeqpacketConn]
1548/// for an examples.
1549///
1550/// # Examples
1551///
1552/// Sending or receiving when it would block a normal socket:
1553///
1554#[cfg_attr(not(target_vendor="apple"), doc="```")]
1555#[cfg_attr(target_vendor="apple", doc="```no_run")]
1556/// use uds_fork::nonblocking::UnixSeqpacketConn;
1557/// use std::io::ErrorKind;
1558///
1559/// let (a, b) = UnixSeqpacketConn::pair().expect("create nonblocking seqpacket pair");
1560///
1561/// // trying to receive when there are no packets waiting
1562/// assert_eq!(a.recv(&mut[0]).unwrap_err().kind(), ErrorKind::WouldBlock);
1563///
1564/// // trying to send when the OS buffer for the connection is full
1565/// loop {
1566/// if let Err(error) = a.send(&[0u8; 1000]) {
1567/// assert_eq!(error.kind(), ErrorKind::WouldBlock);
1568/// break;
1569/// }
1570/// }
1571/// ```
1572//#[deprecated = "Use UnixSeqpacketListener set_nonblocking(true)!"]
1573#[derive(Debug)]
1574#[repr(transparent)]
1575pub struct NonblockingUnixSeqpacketConn
1576{
1577 usc: UnixSeqpacketConn,
1578}
1579
1580impl From<OwnedFd> for NonblockingUnixSeqpacketConn
1581{
1582 fn from(value: OwnedFd) -> Self
1583 {
1584 let usc = UnixSeqpacketConn::from(value);
1585 usc.set_nonblocking(true).unwrap();
1586
1587 return Self{ usc: usc };
1588 }
1589}
1590
1591impl From<NonblockingUnixSeqpacketConn> for OwnedFd
1592{
1593 fn from(value: NonblockingUnixSeqpacketConn) -> Self
1594 {
1595 return value.usc.fd;
1596 }
1597}
1598
1599impl FromRawFd for NonblockingUnixSeqpacketConn
1600{
1601 unsafe
1602 fn from_raw_fd(fd: RawFd) -> Self
1603 {
1604 let usc = unsafe{ UnixSeqpacketConn::from_raw_fd(fd) };
1605 usc.set_nonblocking(true).unwrap();
1606
1607 return Self{ usc: usc };
1608 }
1609}
1610
1611impl AsRawFd for NonblockingUnixSeqpacketConn
1612{
1613 fn as_raw_fd(&self) -> RawFd
1614 {
1615 self.usc.as_raw_fd()
1616 }
1617}
1618impl IntoRawFd for NonblockingUnixSeqpacketConn
1619{
1620 fn into_raw_fd(self) -> RawFd
1621 {
1622 self.usc.into_raw_fd()
1623 }
1624}
1625
1626impl AsFd for NonblockingUnixSeqpacketConn
1627{
1628 fn as_fd(&self) -> BorrowedFd<'_>
1629 {
1630 self.usc.as_fd()
1631 }
1632}
1633
1634impl Deref for NonblockingUnixSeqpacketConn
1635{
1636 type Target = UnixSeqpacketConn;
1637
1638 fn deref(&self) -> &Self::Target
1639 {
1640 &self.usc
1641 }
1642}
1643
1644impl DerefMut for NonblockingUnixSeqpacketConn
1645{
1646 fn deref_mut(&mut self) -> &mut Self::Target
1647 {
1648 &mut self.usc
1649 }
1650}
1651
1652
1653#[cfg(feature = "mio")]
1654pub mod mio_non_blk_conn_enabled
1655{
1656 use std::io;
1657
1658 use mio::event::Source;
1659 use super::NonblockingUnixSeqpacketConn;
1660
1661 impl Source for NonblockingUnixSeqpacketConn
1662 {
1663 fn register(
1664 &mut self,
1665 registry: &mio::Registry,
1666 token: mio::Token,
1667 interests: mio::Interest,
1668 ) -> io::Result<()>
1669 {
1670 self.usc.register(registry, token, interests)
1671 }
1672
1673 fn reregister(
1674 &mut self,
1675 registry: &mio::Registry,
1676 token: mio::Token,
1677 interests: mio::Interest,
1678 ) -> io::Result<()>
1679 {
1680 self.usc.reregister(registry, token, interests)
1681 }
1682
1683 fn deregister(&mut self, registry: &mio::Registry) -> io::Result<()>
1684 {
1685 self.usc.deregister(registry)
1686 }
1687 }
1688}
1689
1690#[cfg(feature = "xio-rs")]
1691pub mod xio_non_blk_conn_enabled
1692{
1693 use xio_rs::{EsInterfaceRegistry, XioChannel, XioEventPipe, XioEventUid, XioResult, event_registry::XioRegistry};
1694
1695 use super::NonblockingUnixSeqpacketConn;
1696
1697 impl<ESSR: EsInterfaceRegistry> XioEventPipe<ESSR, Self> for NonblockingUnixSeqpacketConn
1698 {
1699 fn connect_event_pipe(&mut self, ess: &XioRegistry<ESSR>, ev_uid: XioEventUid, channel: XioChannel) -> XioResult<()>
1700 {
1701 self.usc.connect_event_pipe(ess, ev_uid, channel)
1702 }
1703
1704 fn modify_event_pipe(&mut self, ess: &XioRegistry<ESSR>, ev_uid: XioEventUid, channel: XioChannel) -> XioResult<()>
1705 {
1706 self.usc.modify_event_pipe(ess, ev_uid, channel)
1707 }
1708
1709 fn disconnect_event_pipe(&mut self, ess: &XioRegistry<ESSR>) -> XioResult<()>
1710 {
1711 self.usc.disconnect_event_pipe(ess)
1712 }
1713 }
1714}
1715
1716// can't Deref<Target=UnixSeqpacketConn> because that would include try_clone()
1717// and later set_(read|write)_timeout()
1718impl NonblockingUnixSeqpacketConn
1719{
1720 /// Connects to an unix seqpacket server listening at `path`.
1721 ///
1722 /// This is a wrapper around [`connect_unix_addr()`](#method.connect_unix_addr)
1723 /// for convenience and compatibility with std.
1724 pub
1725 fn connect<P: AsRef<Path>>(path: P) -> Result<Self, io::Error>
1726 {
1727 let addr = UnixSocketAddr::from_path(&path)?;
1728
1729 return Self::connect_unix_addr(&addr);
1730 }
1731
1732 /// Connects to an unix seqpacket server listening at `addr`.
1733 pub
1734 fn connect_unix_addr(addr: &UnixSocketAddr) -> Result<Self, io::Error>
1735 {
1736 let socket = Socket::<SocketSeqPkt>::new(true)?;
1737 socket.set_unix_peer_addr(addr)?;
1738
1739 return Ok(
1740 NonblockingUnixSeqpacketConn
1741 {
1742 usc: UnixSeqpacketConn { fd: socket.into() }
1743 }
1744 );
1745 }
1746
1747 /// Binds to an address before connecting to a listening seqpacet socket.
1748 pub
1749 fn connect_from_to_unix_addr(from: &UnixSocketAddr, to: &UnixSocketAddr) -> Result<Self, io::Error>
1750 {
1751 let socket = Socket::<SocketSeqPkt>::new(true)?;
1752 socket.set_unix_local_addr(from)?;
1753 socket.set_unix_peer_addr(to)?;
1754
1755 return Ok(
1756 NonblockingUnixSeqpacketConn
1757 {
1758 usc: UnixSeqpacketConn { fd: socket.into() }
1759 }
1760 );
1761 }
1762
1763 /// Creates a pair of unix-domain seqpacket conneections connected to each other.
1764 ///
1765 /// # Examples
1766 ///
1767 #[cfg_attr(not(target_vendor="apple"), doc="```")]
1768 #[cfg_attr(target_vendor="apple", doc="```no_run")]
1769 /// let (a, b) = uds_fork::UnixSeqpacketConn::pair().unwrap();
1770 /// assert!(a.local_unix_addr().unwrap().is_unnamed());
1771 /// assert!(b.local_unix_addr().unwrap().is_unnamed());
1772 ///
1773 /// a.send(b"hello").unwrap();
1774 /// b.recv(&mut[0; 20]).unwrap();
1775 /// ```
1776 pub
1777 fn pair() -> Result<(Self, Self), io::Error>
1778 {
1779 let pair = Socket::<SocketSeqPkt>::pair(true)?;
1780
1781 return Ok(
1782 (
1783 Self{ usc: UnixSeqpacketConn { fd: pair.0.into() } },
1784 Self{ usc: UnixSeqpacketConn { fd: pair.1.into() } },
1785 )
1786 );
1787 }
1788
1789 pub
1790 fn try_clone(&self) -> Result<Self, io::Error>
1791 {
1792 let cloned = Socket::<SocketSeqPkt>::try_clone_from(self)?;
1793
1794 return Ok(
1795 NonblockingUnixSeqpacketConn
1796 {
1797 usc: UnixSeqpacketConn { fd: cloned.into() }
1798 }
1799 );
1800 }
1801}
1802
1803impl io::Read for NonblockingUnixSeqpacketConn
1804{
1805 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize>
1806 {
1807 self.recv(buf)
1808 }
1809
1810 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize>
1811 {
1812 self.recv_vectored(bufs).map(|(n, _)| n)
1813 }
1814}
1815
1816impl<'a> io::Read for &'a NonblockingUnixSeqpacketConn
1817{
1818 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize>
1819 {
1820 self.recv(buf)
1821 }
1822
1823 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize>
1824 {
1825 self.recv_vectored(bufs).map(|(n, _)| n)
1826 }
1827}
1828
1829impl io::Write for NonblockingUnixSeqpacketConn
1830{
1831 fn write(&mut self, buf: &[u8]) -> io::Result<usize>
1832 {
1833 self.send(buf)
1834 }
1835
1836 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize>
1837 {
1838 self.send_vectored(bufs)
1839 }
1840
1841 fn flush(&mut self) -> io::Result<()>
1842 {
1843 todo!()
1844 }
1845}
1846
1847
1848/// A non-blocking unix domain listener for sequential-packet connections.
1849///
1850/// Differs from [`UnixSeqpacketListener`](../struct.UnixSeqpacketListener.html)
1851/// in that [`accept()`](struct.NonblockingUnixSeqpacketListener.html#method.accept)
1852/// returns non-blocking [connection sockets](struct.NonblockingUnixSeqpacketConn.html)
1853/// and doesn't block if no client `connect()`ions are pending.
1854///
1855/// # Registering with Xio (xio-rs) a feature = "xio-rs"
1856///
1857/// A `XioEventPipe` is implemented on this function. See [UnixSeqpacketListener]
1858/// for an examples.
1859///
1860/// See examples below.
1861///
1862/// # Registering with Mio (mio) a feature = "mio"
1863///
1864/// A `Source` is implemented on the instance. See [UnixSeqpacketListener]
1865/// for an examples.
1866///
1867/// # Examples
1868///
1869#[cfg_attr(not(target_vendor="apple"), doc="```")]
1870#[cfg_attr(target_vendor="apple", doc="```no_run")]
1871/// use uds_fork::nonblocking::{UnixSeqpacketListener, UnixSeqpacketConn};
1872/// use tempfile::TempDir;
1873/// use std::io::ErrorKind;
1874///
1875/// let dir = tempfile::tempdir().unwrap();
1876/// let mut file_path = dir.path().join("nonblocking_seqpacket_listener2.socket");
1877///
1878/// let listener = UnixSeqpacketListener::bind(&file_path)
1879/// .expect("Cannot create nonblocking seqpacket listener");
1880///
1881/// // doesn't block if no connections are waiting:
1882/// assert_eq!(listener.accept_unix_addr().unwrap_err().kind(), ErrorKind::WouldBlock);
1883///
1884/// // returned connections are nonblocking:
1885/// let _client = UnixSeqpacketConn::connect(&file_path).unwrap();
1886/// let (conn, _addr) = listener.accept_unix_addr().unwrap();
1887/// assert_eq!(conn.recv(&mut[0u8; 20]).unwrap_err().kind(), ErrorKind::WouldBlock);
1888/// ```
1889#[derive(Debug)]
1890#[repr(transparent)]
1891pub struct NonblockingUnixSeqpacketListener
1892{
1893 usl: UnixSeqpacketListener,
1894}
1895
1896impl From<OwnedFd> for NonblockingUnixSeqpacketListener
1897{
1898 fn from(ofd: OwnedFd) -> Self
1899 {
1900 let usl = UnixSeqpacketListener::from(ofd);
1901 usl.set_nonblocking(true).unwrap();
1902
1903 return Self{ usl };
1904 }
1905}
1906
1907impl FromRawFd for NonblockingUnixSeqpacketListener
1908{
1909 unsafe
1910 fn from_raw_fd(fd: RawFd) -> Self
1911 {
1912 let usl = unsafe{ UnixSeqpacketListener::from_raw_fd(fd) };
1913 usl.set_nonblocking(true).unwrap();
1914
1915 return Self{ usl };
1916 }
1917}
1918
1919
1920impl From<NonblockingUnixSeqpacketListener> for OwnedFd
1921{
1922 fn from(value: NonblockingUnixSeqpacketListener) -> Self
1923 {
1924 return value.usl.fd;
1925 }
1926}
1927
1928
1929impl AsRawFd for NonblockingUnixSeqpacketListener
1930{
1931 fn as_raw_fd(&self) -> RawFd
1932 {
1933 self.usl.as_raw_fd()
1934 }
1935}
1936
1937impl IntoRawFd for NonblockingUnixSeqpacketListener
1938{
1939 fn into_raw_fd(self) -> RawFd
1940 {
1941 self.usl.into_raw_fd()
1942 }
1943}
1944
1945impl AsFd for NonblockingUnixSeqpacketListener
1946{
1947 fn as_fd(&self) -> BorrowedFd<'_>
1948 {
1949 self.usl.as_fd()
1950 }
1951}
1952
1953
1954impl Deref for NonblockingUnixSeqpacketListener
1955{
1956 type Target = UnixSeqpacketListener;
1957
1958 fn deref(&self) -> &Self::Target
1959 {
1960 &self.usl
1961 }
1962}
1963
1964impl DerefMut for NonblockingUnixSeqpacketListener
1965{
1966 fn deref_mut(&mut self) -> &mut Self::Target
1967 {
1968 &mut self.usl
1969 }
1970}
1971
1972impl NonblockingUnixSeqpacketListener
1973{
1974 /// Creates a socket that listens for seqpacket connections on the specified socket file.
1975 pub
1976 fn bind<P: AsRef<Path>>(path: P) -> Result<Self, io::Error>
1977 {
1978 let addr = UnixSocketAddr::from_path(&path)?;
1979
1980 return Self::bind_unix_addr(&addr);
1981 }
1982
1983 /// Creates a socket that listens for seqpacket connections on the specified address.
1984 pub
1985 fn bind_unix_addr(addr: &UnixSocketAddr) -> Result<Self, io::Error>
1986 {
1987 let socket = Socket::<SocketSeqPkt>::new(true)?;
1988 socket.set_unix_local_addr(addr)?;
1989 socket.start_listening()?;
1990
1991 return Ok( Self{ usl: UnixSeqpacketListener{ fd: socket.into() }} );
1992 }
1993
1994 /// Accepts a non-blocking connection, non-blockingly.
1995 ///
1996 /// # Examples
1997 ///
1998 /// Doesn't block if no connections are waiting:
1999 ///
2000 #[cfg_attr(not(target_vendor="apple"), doc="```")]
2001 #[cfg_attr(target_vendor="apple", doc="```no_run")]
2002 /// # use uds_fork::nonblocking::UnixSeqpacketListener;
2003 /// # use std::io::ErrorKind;
2004 /// # use tempfile::TempDir;
2005 ///
2006 /// let dir = tempfile::tempdir().unwrap();
2007 /// let mut file_path = dir.path().join("nonblocking_seqpacket_listener3.socket");
2008 ///
2009 /// let listener = UnixSeqpacketListener::bind(&file_path)
2010 /// .expect("Cannot create nonblocking seqpacket listener");
2011 /// assert_eq!(listener.accept_unix_addr().unwrap_err().kind(), ErrorKind::WouldBlock);
2012 /// ```
2013 pub
2014 fn accept_unix_addr(&self) -> Result<(NonblockingUnixSeqpacketConn, UnixSocketAddr), io::Error>
2015 {
2016 let (socket, addr) = Socket::<SocketSeqPkt>::accept_from(&self, true)?;
2017 let conn = NonblockingUnixSeqpacketConn { usc: UnixSeqpacketConn{ fd: socket.into() }};
2018
2019 return Ok((conn, addr));
2020 }
2021}
2022
2023
2024
2025#[cfg(feature = "mio")]
2026pub mod mio_non_blk_listener_enabled
2027{
2028 use std::{io, os::fd::AsRawFd};
2029
2030 use mio::{event::Source, unix::SourceFd};
2031 use super::NonblockingUnixSeqpacketListener;
2032
2033 impl Source for NonblockingUnixSeqpacketListener
2034 {
2035 fn register(
2036 &mut self,
2037 registry: &mio::Registry,
2038 token: mio::Token,
2039 interests: mio::Interest,
2040 ) -> io::Result<()>
2041 {
2042 self.usl.register(registry, token, interests)
2043 }
2044
2045 fn reregister(
2046 &mut self,
2047 registry: &mio::Registry,
2048 token: mio::Token,
2049 interests: mio::Interest,
2050 ) -> io::Result<()>
2051 {
2052 self.usl.reregister(registry, token, interests)
2053 }
2054
2055 fn deregister(&mut self, registry: &mio::Registry) -> io::Result<()>
2056 {
2057 self.usl.deregister(registry)
2058 }
2059 }
2060}
2061
2062#[cfg(feature = "xio-rs")]
2063pub mod xio_non_blk_listener_enabled
2064{
2065 use xio_rs::{EsInterfaceRegistry, XioChannel, XioEventPipe, XioEventUid, XioResult, event_registry::XioRegistry};
2066
2067 use super::NonblockingUnixSeqpacketListener;
2068
2069 impl<ESSR: EsInterfaceRegistry> XioEventPipe<ESSR, Self> for NonblockingUnixSeqpacketListener
2070 {
2071 fn connect_event_pipe(&mut self, ess: &XioRegistry<ESSR>, ev_uid: XioEventUid, channel: XioChannel) -> XioResult<()>
2072 {
2073
2074 self.usl.connect_event_pipe(ess, ev_uid, channel)
2075 }
2076
2077 fn modify_event_pipe(&mut self, ess: &XioRegistry<ESSR>, ev_uid: XioEventUid, channel: XioChannel) -> XioResult<()>
2078 {
2079 self.usl.modify_event_pipe(ess, ev_uid, channel)
2080 }
2081
2082 fn disconnect_event_pipe(&mut self, ess: &XioRegistry<ESSR>) -> XioResult<()>
2083 {
2084 self.usl.disconnect_event_pipe(ess)
2085 }
2086 }
2087}