Skip to main content

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, &[], 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)], 
435            fds.iter().map(|fd| fd.as_raw_fd()).collect::<Vec<RawFd>>().as_slice(), None)
436    }
437
438    /// Sends a packet with associated file descriptors. Raw descriptors.
439    pub unsafe 
440    fn send_fds_raw(&self, bytes: &[u8], fds: &[RawFd]) -> Result<usize, io::Error> 
441    {
442        send_ancillary(&self, None, MSG_EOR, &[IoSlice::new(bytes)], 
443            fds, None)
444    }
445
446    /// Receives a packet and associated file descriptors. A legacy method which 
447    /// was in this crate since its author added it.
448    /// 
449    /// A FDs are placed into Vec with the specific capacity. 
450    /// 
451    /// A FDs will be truncated if the capacity is not large enough.
452    /// 
453    /// See a 
454    #[cfg_attr(not(feature="unsatable_preview"), doc="Self::recv_vectored_with_ancillary")]
455    #[cfg_attr(feature="unsatable_preview", doc="[Self::recv_vectored_with_ancillary]")]
456    ///  for a new stdlib approach.
457    /// 
458    /// # Returns 
459    /// 
460    /// * 0 - amount of bytes received
461    /// 
462    /// * 1 - is truncated
463    /// 
464    /// * 2 - a fd buffer length
465    pub 
466    fn recv_fds(&self, byte_buffer: &mut[u8], fd_buf: &mut Vec<OwnedFd>) -> Result<(usize, bool, usize), io::Error> 
467    {
468        recv_fds(&self, None, &mut[IoSliceMut::new(byte_buffer)], fd_buf)
469    }
470
471    /// Receives a packet and associated file descriptors. A legacy method which 
472    /// was in this crate since its author added it.
473    /// 
474    /// A FDs are placed into pre-allocated mutable slice. Received valies are stored
475    /// in reception sequence. The first [Option::None] does mean the rest are None too.
476    /// 
477    /// A FDs will be truncated if the length of the slice is not enough.
478    /// 
479    /// See a 
480    #[cfg_attr(not(feature="unsatable_preview"), doc="Self::recv_vectored_with_ancillary")]
481    #[cfg_attr(feature="unsatable_preview", doc="[Self::recv_vectored_with_ancillary]")]
482    /// for a new stdlib approach.
483    /// 
484    /// # Returns 
485    /// 
486    /// * 0 - amount of bytes received
487    /// 
488    /// * 1 - is truncated
489    /// 
490    /// * 2 - a fd buffer length
491    pub 
492    fn recv_slice_fds(&self,  buf: &mut[u8], fd_buf: &mut [Option<OwnedFd>]) -> Result<(usize, usize), io::Error> 
493    {
494        recv_slice_fds(self, None, &mut[IoSliceMut::new(buf)], fd_buf)
495            .map(|(bytes, _, fds)| (bytes, fds) )
496    }
497
498    /// A old (provided by crate, legacy) parser of the ancillary data.
499    /// 
500    /// Returns an iterator to the ancillary data.
501    /// 
502    /// # Returns
503    /// 
504    /// A [Result] is returned with tuple:
505    /// 
506    /// * `0` - a count of bytes.
507    /// 
508    /// * `1` - [Ancillary] a ancillary iterator.
509    /// 
510    pub 
511    fn recv_vectored_ancillary<'a>(
512        &self,
513        flags: i32, 
514        bufs: &mut [IoSliceMut<'_>],
515        ancillary: &'a mut AncillaryBuf,
516    ) -> Result<(usize, Ancillary<'a>), io::Error> 
517    {
518        recv_ancillary(self, None, flags, bufs, ancillary)
519    }
520
521    /// A new (provided by std) parser of the ancillary data
522    /// 
523    /// Unstable and extremely unsafe. Rust devs did not provide an access
524    /// to the internal reference to the buffer in [SocketAncillary], so
525    /// there is no access to the buffer and its length. For this reason a
526    /// very bad approach to overcome this is used.
527    /// 
528    /// > Receives data and ancillary data from socket.
529    /// > 
530    /// > On success, returns the number of bytes read, if the data was 
531    /// > truncated and the address from whence the msg came.
532    /// 
533    /// # Returns
534    /// 
535    /// A [Result] is returned with tuple:
536    /// 
537    /// * `0` - a count of bytes.
538    /// 
539    /// * `1` - was msg truncated
540    /// 
541    /// # Example
542    /// 
543    /// ```ignore
544    ///  let mut buf = [0_u8; 256];
545    /// let bufs = &mut [IoSliceMut::new(&mut buf[..])];
546    /// 
547    /// let mut ancillary_buffer = [0; 128];
548    /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]);
549    /// 
550    /// let (count, trunc) = 
551    ///     freya_side_b.recv_vectored_with_ancillary(bufs, &mut ancillary).unwrap();
552    /// ```
553    #[cfg(feature = "unsatable_preview")]
554    pub 
555    fn recv_vectored_with_ancillary(
556        &self,
557        flags: i32, 
558        bufs: &mut [IoSliceMut<'_>],
559        ancillary: &mut SocketAncillary<'_>,
560    ) -> Result<(usize, bool), io::Error>
561    {
562        unsafe { recv_ancillary_std(&self, flags, bufs, ancillary) }
563            .map(|(count, trunc, _)| (count, trunc))
564    }
565
566    /// A new (provided by std) parser of the ancillary data
567    /// 
568    /// Unstable and extremely unsafe. Rust devs did not provide an access
569    /// to the internal reference to the buffer in [SocketAncillary], so
570    /// there is no access to the buffer and its length. For this reason a
571    /// very bad approach to overcome this is used.
572    /// 
573    /// > Receives data and ancillary data providing the source of msg.
574    /// > 
575    /// > On success, returns the number of bytes read, if the data was 
576    /// > truncated and the address from whence the msg came.
577    /// 
578    /// # Returns
579    /// 
580    /// A [Result] is returned with tuple:
581    /// 
582    /// * `0` - a count of bytes.
583    /// 
584    /// * `1` - was msg truncated
585    /// 
586    /// * `2` - a source address
587    /// 
588    /// # Example
589    /// 
590    /// ```ignore
591    /// let mut buf = [0_u8; 256];
592    /// let bufs = &mut [IoSliceMut::new(&mut buf[..])];
593    /// 
594    /// let mut ancillary_buffer = [0; 128];
595    /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]);
596    /// 
597    /// let (count, trunc, from) = 
598    ///     freya_side_b.recv_vectored_with_ancillary(bufs, &mut ancillary).unwrap();
599    /// ```
600    #[cfg(feature = "unsatable_preview")]
601    pub 
602    fn recv_vectored_with_ancillary_from(
603        &self,
604        flags: i32,
605        bufs: &mut [IoSliceMut<'_>],
606        ancillary: &mut SocketAncillary<'_>,
607    ) -> Result<(usize, bool, UnixSocketAddr), io::Error>
608    {
609        unsafe { recv_ancillary_std(&self, flags, bufs, ancillary) }
610    }
611
612    /// A new (provided by std) parser of the ancillary data. 
613    /// 
614    /// Rust #![feature(unix_socket_ancillary_data)]
615    /// 
616    /// Unstable and extremely unsafe. Rust devs did not provide an access
617    /// to the internal reference to the buffer in [SocketAncillary], so
618    /// there is no access to the buffer and its length. For this reason a
619    /// very bad approach to overcome this is used.
620    /// 
621    /// > Sends data and ancillary data on the current socket.
622    /// >
623    /// > On success, returns the number of bytes written.
624    /// 
625    /// Crate: feature = unsatable_preview
626    /// 
627    /// # Arguments
628    /// 
629    /// * `flags` - a flags which are passed to [libc::recvmsg].
630    /// 
631    /// * `bufs` - an [IoSlice] buffers.
632    /// 
633    /// * `ancillary` - packed ancillary data
634    /// 
635    /// # Example 
636    /// 
637    /// ```ignore
638    /// let buf0 = b"Here I come";
639    /// let mut ancillary_buffer = [0; 128];
640    /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]);
641    /// 
642    /// let fds = [OwnedFd::from(a).into_raw_fd(), OwnedFd::from(b).into_raw_fd(), OwnedFd::from(aa).into_raw_fd()];
643    /// 
644    /// ancillary.add_fds(&fds[..]);
645    /// 
646    /// freya_side_a.send_vectored_with_ancillary(&[IoSlice::new(buf0.as_slice())], &mut ancillary)
647    ///     .expect("send stdin, stdout and stderr");
648    /// 
649    /// ```
650    #[cfg(feature = "unsatable_preview")]
651    pub 
652    fn send_vectored_with_ancillary(
653        &self,
654        flags: i32,
655        bufs: &[IoSlice<'_>],
656        ancillary: &mut SocketAncillary<'_>,
657    ) -> io::Result<usize> 
658    {
659        unsafe { send_ancillary_std(&self, None, flags, bufs,  ancillary) }
660    }
661
662    /// A new (provided by std) parser of the ancillary data. 
663    /// 
664    /// Rust #![feature(unix_socket_ancillary_data)]
665    /// 
666    /// Unstable and extremely unsafe. Rust devs did not provide an access
667    /// to the internal reference to the buffer in [SocketAncillary], so
668    /// there is no access to the buffer and its length. For this reason a
669    /// very bad approach to overcome this is used.
670    /// 
671    /// > Sends data and ancillary data on the socket to the specified address.
672    /// >
673    /// > On success, returns the number of bytes written.
674    /// 
675    /// Crate: feature = unsatable_preview
676    /// 
677    /// # Arguments
678    /// 
679    /// * `flags` - a flags which are passed to [libc::recvmsg].
680    /// 
681    /// * `to` - a destination.
682    /// 
683    /// * `bufs` - an [IoSlice] buffers.
684    /// 
685    /// * `ancillary` - packed ancillary data
686    /// 
687    /// # Example 
688    /// 
689    /// ```ignore
690    /// let buf0 = b"Here I come";
691    /// let mut ancillary_buffer = [0; 128];
692    /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]);
693    /// 
694    /// let fds = 
695    ///     [OwnedFd::from(a).into_raw_fd(), OwnedFd::from(b).into_raw_fd(), OwnedFd::from(aa).into_raw_fd()];
696    /// 
697    /// ancillary.add_fds(&fds[..]);
698    /// 
699    /// let dst = UnixSocketAddr::from_abstract("@test");
700    /// 
701    /// freya_side_a
702    ///     .send_vectored_with_ancillary_to(0, &dst, &[IoSlice::new(buf0.as_slice())], &mut ancillary)
703    ///     .expect("send stdin, stdout and stderr");
704    /// 
705    /// ```
706    #[cfg(feature = "unsatable_preview")]
707    pub 
708    fn send_vectored_with_ancillary_to(
709        &self,
710        flags: i32,
711        to: &UnixSocketAddr,
712        bufs: &[IoSlice<'_>],
713        ancillary: &mut SocketAncillary<'_>,
714    ) -> io::Result<usize> 
715    {
716        unsafe { send_ancillary_std(&self, Some(to), flags, bufs,  ancillary) }
717    }
718
719    /// Receives a packet without removing it from the incoming queue.
720    ///
721    /// # Examples
722    ///
723    #[cfg_attr(not(target_vendor="apple"), doc="```")]
724    #[cfg_attr(target_vendor="apple", doc="```no_run")]
725    /// let (a, b) = uds_fork::UnixSeqpacketConn::pair().unwrap();
726    /// a.send(b"hello").unwrap();
727    /// let mut buf = [0u8; 10];
728    /// assert_eq!(b.peek(&mut buf[..1]).unwrap(), 1);
729    /// assert_eq!(&buf[..2], &[b'h', 0]);
730    /// assert_eq!(b.peek(&mut buf).unwrap(), 5);
731    /// assert_eq!(&buf[..5], b"hello");
732    /// assert_eq!(b.recv(&mut buf).unwrap(), 5);
733    /// assert_eq!(&buf[..5], b"hello");
734    /// ```
735    pub 
736    fn peek(&self,  buffer: &mut[u8]) -> Result<usize, io::Error> 
737    {
738        let ptr = buffer.as_ptr() as *mut c_void;
739        let flags = MSG_NOSIGNAL | MSG_PEEK;
740        let received = cvt_r!(unsafe { recv(self.fd.as_raw_fd(), ptr, buffer.len(), flags) })?;
741        
742        return Ok(received as usize);
743    }
744
745    /// Receives a packet without removing it from the incoming queue.
746    ///
747    /// The returned `bool` indicates whether the packet was truncated due to
748    /// the combined buffers being too small.
749    pub 
750    fn peek_vectored(&self,  buffers: &mut[IoSliceMut]) -> Result<(usize, bool), io::Error> 
751    {
752        recv_ancillary(&self, None, MSG_PEEK, buffers, &mut[])
753            .map(|(bytes, ancillary)| (bytes, ancillary.message_truncated()) )
754    }
755
756    /// Returns the value of the `SO_ERROR` option.
757    ///
758    /// This might only provide errors generated from nonblocking `connect()`s,
759    /// which this library doesn't support. It is therefore unlikely to be 
760    /// useful, but is provided for parity with stream counterpart in std.
761    ///
762    /// # Examples
763    ///
764    #[cfg_attr(not(target_vendor="apple"), doc="```")]
765    #[cfg_attr(target_vendor="apple", doc="```no_run")]
766    /// let (a, b) = uds_fork::UnixSeqpacketConn::pair().unwrap();
767    /// drop(b);
768    ///
769    /// assert!(a.send(b"anyone there?").is_err());
770    /// assert!(a.take_error().unwrap().is_none());
771    /// ```
772    pub 
773    fn take_error(&self) -> Result<Option<io::Error>, io::Error> 
774    {
775        take_error(&self)
776    }
777
778
779    /// Creates a new file descriptor also pointing to this side of this connection.
780    ///
781    /// # Examples
782    ///
783    /// Both new and old can send and receive, and share queues:
784    ///
785    #[cfg_attr(not(target_vendor="apple"), doc="```")]
786    #[cfg_attr(target_vendor="apple", doc="```no_run")]
787    /// let (a1, b) = uds_fork::nonblocking::UnixSeqpacketConn::pair().unwrap();
788    /// let a2 = a1.try_clone().unwrap();
789    ///
790    /// a1.send(b"first").unwrap();
791    /// a2.send(b"second").unwrap();
792    ///
793    /// let mut buf = [0u8; 20];
794    /// let len = b.recv(&mut buf).unwrap();
795    /// assert_eq!(&buf[..len], b"first");
796    /// b.send(b"hello first").unwrap();
797    /// let len = b.recv(&mut buf).unwrap();
798    /// assert_eq!(&buf[..len], b"second");
799    /// b.send(b"hello second").unwrap();
800    ///
801    /// let len = a2.recv(&mut buf).unwrap();
802    /// assert_eq!(&buf[..len], b"hello first");
803    /// let len = a1.recv(&mut buf).unwrap();
804    /// assert_eq!(&buf[..len], b"hello second");
805    /// ```
806    ///
807    /// Clone can still be used after the first one has been closed:
808    ///
809    #[cfg_attr(not(target_vendor="apple"), doc="```")]
810    #[cfg_attr(target_vendor="apple", doc="```no_run")]
811    /// let (a, b1) = uds_fork::nonblocking::UnixSeqpacketConn::pair().unwrap();
812    /// a.send(b"hello").unwrap();
813    ///
814    /// let b2 = b1.try_clone().unwrap();
815    /// drop(b1);
816    /// assert_eq!(b2.recv(&mut[0; 10]).unwrap(), "hello".len());
817    /// ```
818    pub 
819    fn try_clone(&self) -> Result<Self, io::Error> 
820    {
821        let cloned = Socket::<SocketSeqPkt>::try_clone_from(self)?;
822
823        return Ok(UnixSeqpacketConn { fd: cloned.into() });
824    }
825
826    /// Sets the read timeout to the duration specified.
827    ///
828    /// If the value specified is `None`, then `recv()` and its variants will
829    /// block indefinitely.  
830    /// An error is returned if the duration is zero.
831    ///
832    /// The duration is rounded to microsecond precission.
833    /// Currently it's rounded down except if that would make it all zero.
834    ///
835    /// # Operating System Support
836    ///
837    /// On Illumos (and pressumably also Solaris) timeouts appears not to work
838    /// for unix domain sockets.
839    ///
840    /// # Examples
841    ///
842    #[cfg_attr(not(any(target_vendor="apple", target_os="illumos", target_os="solaris")), doc="```")]
843    #[cfg_attr(any(target_vendor="apple", target_os="illumos", target_os="solaris"), doc="```no_run")]
844    /// use std::io::ErrorKind;
845    /// use std::time::Duration;
846    /// use uds_fork::UnixSeqpacketConn;
847    ///
848    /// let (a, b) = UnixSeqpacketConn::pair().unwrap();
849    /// a.set_read_timeout(Some(Duration::new(0, 2_000_000))).unwrap();
850    /// let error = a.recv(&mut[0; 1024]).unwrap_err();
851    /// assert_eq!(error.kind(), ErrorKind::WouldBlock);
852    /// ```
853    pub 
854    fn set_read_timeout(&self, timeout: Option<Duration>) -> Result<(), io::Error> 
855    {
856        set_timeout(self.fd.as_fd(), TimeoutDirection::Read, timeout)
857    }
858
859    /// Returns the read timeout of this socket.
860    ///
861    /// `None` is returned if there is no timeout.
862    ///
863    /// Note that subsecond parts might have been be rounded by the OS
864    /// (in addition to the rounding to microsecond in `set_read_timeout()`).
865    ///
866    /// # Examples
867    ///
868    #[cfg_attr(not(any(target_vendor="apple", target_os="illumos", target_os="solaris")), doc="```")]
869    #[cfg_attr(any(target_vendor="apple", target_os="illumos", target_os="solaris"), doc="```no_run")]
870    /// use uds_fork::UnixSeqpacketConn;
871    /// use std::time::Duration;
872    ///
873    /// let timeout = Some(Duration::new(2, 0));
874    /// let conn = UnixSeqpacketConn::pair().unwrap().0;
875    /// conn.set_read_timeout(timeout).unwrap();
876    /// assert_eq!(conn.read_timeout().unwrap(), timeout);
877    /// ```
878    pub 
879    fn read_timeout(&self) -> Result<Option<Duration>, io::Error> 
880    {
881        get_timeout(self.fd.as_fd(), TimeoutDirection::Read)
882    }
883
884    /// Sets the write timeout to the duration specified.
885    ///
886    /// If the value specified is `None`, then `send()` and its variants will
887    /// block indefinitely.  
888    /// An error is returned if the duration is zero.
889    ///
890    /// # Operating System Support
891    ///
892    /// On Illumos (and pressumably also Solaris) timeouts appears not to work
893    /// for unix domain sockets.
894    ///
895    /// # Examples
896    ///
897    #[cfg_attr(not(any(target_vendor="apple", target_os="illumos", target_os="solaris")), doc="```")]
898    #[cfg_attr(any(target_vendor="apple", target_os="illumos", target_os="solaris"), doc="```no_run")]
899    /// # use std::io::ErrorKind;
900    /// # use std::time::Duration;
901    /// # use uds_fork::UnixSeqpacketConn;
902    /// #
903    /// let (conn, _other) = UnixSeqpacketConn::pair().unwrap();
904    /// conn.set_write_timeout(Some(Duration::new(0, 500 * 1000))).unwrap();
905    /// loop {
906    ///     if let Err(e) = conn.send(&[0; 1000]) {
907    ///         assert_eq!(e.kind(), ErrorKind::WouldBlock, "{}", e);
908    ///         break
909    ///     }
910    /// }
911    /// ```
912    pub 
913    fn set_write_timeout(&self,  timeout: Option<Duration>)-> Result<(), io::Error> 
914    {
915        set_timeout(self.fd.as_fd(), TimeoutDirection::Write, timeout)
916    }
917
918    /// Returns the write timeout of this socket.
919    ///
920    /// `None` is returned if there is no timeout.
921    ///
922    /// # Examples
923    ///
924    #[cfg_attr(not(target_vendor="apple"), doc="```")]
925    #[cfg_attr(target_vendor="apple", doc="```no_run")]
926    /// let conn = uds_fork::UnixSeqpacketConn::pair().unwrap().0;
927    /// assert!(conn.write_timeout().unwrap().is_none());
928    /// ```
929    pub 
930    fn write_timeout(&self) -> Result<Option<Duration>, io::Error> 
931    {
932        get_timeout(self.fd.as_fd(), TimeoutDirection::Write)
933    }
934
935    /// Enables or disables nonblocking mode.
936    ///
937    /// Consider using the nonblocking variant of this type instead.
938    /// This method mainly exists for feature parity with std's `UnixStream`.
939    ///
940    /// # Examples
941    ///
942    /// Trying to receive when there are no packets waiting:
943    ///
944    #[cfg_attr(not(target_vendor="apple"), doc="```")]
945    #[cfg_attr(target_vendor="apple", doc="```no_run")]
946    /// # use std::io::ErrorKind;
947    /// # use uds_fork::UnixSeqpacketConn;
948    /// let (a, b) = UnixSeqpacketConn::pair().expect("create seqpacket pair");
949    /// a.set_nonblocking(true).unwrap();
950    /// assert_eq!(a.recv(&mut[0; 20]).unwrap_err().kind(), ErrorKind::WouldBlock);
951    /// ```
952    ///
953    /// Trying to send when the OS buffer for the connection is full:
954    ///
955    #[cfg_attr(not(target_vendor="apple"), doc="```")]
956    #[cfg_attr(target_vendor="apple", doc="```no_run")]
957    /// # use std::io::ErrorKind;
958    /// # use uds_fork::UnixSeqpacketConn;
959    /// let (a, b) = UnixSeqpacketConn::pair().expect("create seqpacket pair");
960    /// a.set_nonblocking(true).unwrap();
961    /// loop {
962    ///     if let Err(error) = a.send(&[b'#'; 1000]) {
963    ///         assert_eq!(error.kind(), ErrorKind::WouldBlock);
964    ///         break;
965    ///     }
966    /// }
967    /// ```
968    pub 
969    fn set_nonblocking(&self,  nonblocking: bool) -> Result<(), io::Error> 
970    {
971        set_nonblocking(&self, nonblocking)
972    }
973
974    /// Shuts down the read, write, or both halves of this connection.
975    pub 
976    fn shutdown(&self, how: Shutdown) -> io::Result<()> 
977    {
978        let how = 
979            match how 
980            {
981                Shutdown::Read => libc::SHUT_RD,
982                Shutdown::Write => libc::SHUT_WR,
983                Shutdown::Both => libc::SHUT_RDWR,
984            };
985
986        unsafe { cvt!(libc::shutdown(self.as_raw_fd(), how)) }?;
987        
988        return Ok(());
989    }
990
991    fn read_string(&self, buf: &mut String) -> io::Result<usize>
992    {
993        let mut read_size: u32 = 0;
994
995        let _ = 
996            cvt!(unsafe { libc::ioctl(self.fd.as_raw_fd(), libc::FIONREAD, &mut read_size) })?;
997
998        let mut byte_buf = vec![0_u8; read_size as usize];
999
1000        let _ = self.recv(&mut byte_buf)?;
1001
1002        let str_slice = 
1003            str::from_utf8(&byte_buf)
1004                .map_err(|e|
1005                    io::Error::new(ErrorKind::Other, e)
1006                )?;
1007
1008        buf.push_str(str_slice);
1009
1010        return Ok(byte_buf.len());
1011    }
1012}
1013
1014impl io::Read for UnixSeqpacketConn
1015{
1016    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> 
1017    {
1018        self.recv(buf)
1019    }
1020
1021    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> 
1022    {
1023        self.recv_vectored(bufs).map(|(n, _)| n)
1024    }
1025
1026    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> 
1027    {
1028        self.read_string(buf)
1029    }
1030}
1031
1032impl<'a> io::Read for &'a UnixSeqpacketConn
1033{
1034    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> 
1035    {
1036        self.recv(buf)
1037    }
1038
1039    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> 
1040    {
1041        self.recv_vectored(bufs).map(|(n, _)| n)
1042    }
1043
1044    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> 
1045    {
1046        self.read_string(buf)
1047    }
1048}
1049
1050impl io::Write for UnixSeqpacketConn
1051{
1052    fn write(&mut self, buf: &[u8]) -> io::Result<usize> 
1053    {
1054        self.send(buf)
1055    }
1056
1057    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> 
1058    {
1059        self.send_vectored(bufs)
1060    }
1061
1062    fn flush(&mut self) -> io::Result<()> 
1063    {
1064        return Ok(());
1065    }
1066}
1067
1068/// An unix domain listener for sequential packet connections.
1069///
1070/// See [`UnixSeqpacketConn`](struct.UnixSeqpacketConn.html) for a description
1071/// of this type of connection.
1072/// 
1073/// # Registering with Xio (xio-rs) a feature = "xio-rs"
1074/// 
1075/// A `XioEventPipe` is implemented on this function. During initial registration
1076/// an attempt set `nonblocking` mode is performed during initial registration.
1077/// 
1078/// See examples below.
1079/// 
1080/// # Registering with Mio (mio) a feature = "mio"
1081/// 
1082/// A `Source` is implemented on the instance.During initial registration
1083/// an attempt set `nonblocking` mode is performed during initial registration.
1084///
1085/// # Examples
1086///
1087#[cfg_attr(not(target_vendor="apple"), doc="```")]
1088#[cfg_attr(target_vendor="apple", doc="```no_run")]
1089/// use tempfile::TempDir;
1090/// 
1091/// let dir = tempfile::tempdir().unwrap();
1092/// let mut file_path = dir.path().join("seqpacket_listener.socket");
1093/// 
1094/// let listener = uds_fork::UnixSeqpacketListener::bind(&file_path)
1095///     .expect("Create seqpacket listener");
1096/// let _client = uds_fork::UnixSeqpacketConn::connect(&file_path).unwrap();
1097/// let (conn, _addr) = listener.accept_unix_addr().unwrap();
1098/// conn.send(b"Welcome").unwrap();
1099/// ```
1100/// 
1101/// ### Xio
1102/// 
1103/// ```ignore
1104/// let listener = uds_fork::UnixSeqpacketListener::bind(file_path).unwrap();
1105/// 
1106/// let mut reg = XioPollRegistry::<ESS>::new().unwrap();
1107/// let mut event_buf = XioPollRegistry::<ESS>::allocate_events(128.try_into().unwrap());
1108/// 
1109/// // either
1110/// let a_wrapped =
1111///     reg.get_registry()
1112///         .en_register_wrap(listener, XioEventUid::manual(1), XioChannel::INPUT)
1113///         .unwrap();
1114///  
1115/// // or 
1116///     reg.get_registry()
1117///         .en_register&mut listener, XioEventUid::manual(1), XioChannel::INPUT)
1118///         .unwrap();
1119/// 
1120/// // so depending on the method, use either:
1121/// a_wrapped.inner();
1122/// 
1123/// // or continue using a directly
1124/// ```
1125/// 
1126/// ### Mio:
1127/// 
1128/// ```ignore
1129/// let listener = uds_fork::UnixSeqpacketListener::bind(file_path).unwrap();
1130/// 
1131/// let mut poll = Poll::new().expect("create mio poll");
1132/// let mut events = Events::with_capacity(10);
1133/// 
1134/// poll.registry()
1135///     .register(&mut listener, Token(1), Interest::READABLE)
1136///     .unwrap();
1137/// // ...
1138/// ``` 
1139#[derive(Debug)]
1140#[repr(transparent)]
1141pub struct UnixSeqpacketListener 
1142{
1143    fd: OwnedFd
1144}
1145
1146
1147impl From<OwnedFd> for UnixSeqpacketListener
1148{
1149    fn from(ofd: OwnedFd) -> Self 
1150    {
1151        let sa_fam = get_socket_family(&ofd).unwrap();
1152        let sa_type = get_socket_type(&ofd).unwrap() & 0x00000FFF;
1153
1154        if sa_fam as i32 != libc::AF_UNIX || sa_type != libc::SOCK_SEQPACKET
1155        {
1156            panic!("assertion trap: provided FD is not AF_UNIX & SOCK_SEQPACKET, {} {}", 
1157                sa_fam, sa_type);
1158        }
1159
1160        return UnixSeqpacketListener{ fd: ofd };
1161    }
1162}
1163
1164impl From<UnixSeqpacketListener> for OwnedFd
1165{
1166    fn from(value: UnixSeqpacketListener) -> Self 
1167    {
1168        return value.fd;
1169    }
1170}
1171
1172impl FromRawFd for UnixSeqpacketListener
1173{
1174    unsafe 
1175    fn from_raw_fd(fd: RawFd) -> Self 
1176    {
1177        UnixSeqpacketListener::from( unsafe { OwnedFd::from_raw_fd(fd) } )
1178    }
1179}
1180
1181impl AsRawFd for UnixSeqpacketListener
1182{
1183    fn as_raw_fd(&self) -> RawFd 
1184    {
1185        self.fd.as_raw_fd()
1186    }
1187}
1188
1189impl IntoRawFd for UnixSeqpacketListener
1190{
1191    fn into_raw_fd(self) -> RawFd 
1192    {
1193        self.fd.into_raw_fd()
1194    }
1195}
1196
1197impl AsFd for UnixSeqpacketListener
1198{
1199    fn as_fd(&self) -> BorrowedFd<'_> 
1200    {
1201        self.fd.as_fd()
1202    }
1203}
1204
1205#[cfg(feature = "mio")]
1206pub mod mio_listener_enabled
1207{
1208    use std::{io, os::fd::AsRawFd};
1209
1210    use mio::{event::Source, unix::SourceFd};
1211    use crate::UnixSeqpacketListener;
1212
1213    impl Source for UnixSeqpacketListener
1214    {
1215        fn register(
1216            &mut self,
1217            registry: &mio::Registry,
1218            token: mio::Token,
1219            interests: mio::Interest,
1220        ) -> io::Result<()> 
1221        {
1222            self.set_nonblocking(true)?;
1223            
1224            SourceFd(&self.fd.as_raw_fd()).register(registry, token, interests)
1225        }
1226    
1227        fn reregister(
1228            &mut self,
1229            registry: &mio::Registry,
1230            token: mio::Token,
1231            interests: mio::Interest,
1232        ) -> io::Result<()> 
1233        {
1234            SourceFd(&self.fd.as_raw_fd()).reregister(registry, token, interests)
1235        }
1236    
1237        fn deregister(&mut self, registry: &mio::Registry) -> io::Result<()> 
1238        {
1239            SourceFd(&self.fd.as_raw_fd()).deregister(registry)
1240        }
1241    }
1242}
1243
1244#[cfg(feature = "xio-rs")]
1245pub mod xio_listener_enabled
1246{
1247    use xio_rs::{EsInterfaceRegistry, XioChannel, XioEventPipe, XioEventUid, XioResult, event_registry::XioRegistry};
1248
1249    use crate::UnixSeqpacketListener;
1250
1251    impl<ESSR: EsInterfaceRegistry> XioEventPipe<ESSR, Self> for UnixSeqpacketListener
1252    {
1253        fn connect_event_pipe(&mut self, ess: &XioRegistry<ESSR>, ev_uid: XioEventUid, channel: XioChannel) -> XioResult<()> 
1254        {
1255            self.set_nonblocking(true)?;
1256            
1257            ess.get_ev_sys().en_register(&self.fd, ev_uid, channel)
1258        }
1259    
1260        fn modify_event_pipe(&mut self, ess: &XioRegistry<ESSR>, ev_uid: XioEventUid, channel: XioChannel) -> XioResult<()> 
1261        {
1262            ess.get_ev_sys().re_register(&self.fd, ev_uid, channel)
1263        }
1264    
1265        fn disconnect_event_pipe(&mut self, ess: &XioRegistry<ESSR>) -> XioResult<()> 
1266        {
1267            ess.get_ev_sys().de_register(&self.fd)
1268        }
1269    }
1270}
1271
1272impl UnixSeqpacketListener 
1273{
1274    /// Creates a socket that listens for seqpacket connections on the specified socket file.
1275    pub 
1276    fn bind<P: AsRef<Path>>(path: P) -> Result<Self, io::Error> 
1277    {
1278        let addr = UnixSocketAddr::from_path(path.as_ref())?;
1279        
1280        return Self::bind_unix_addr(&addr);
1281    }
1282
1283    /// Creates a socket that listens for seqpacket connections on the specified address.
1284    pub 
1285    fn bind_unix_addr(addr: &UnixSocketAddr) -> Result<Self, io::Error> 
1286    {
1287        let socket = Socket::<SocketSeqPkt>::new(false)?;
1288
1289        socket.set_unix_local_addr(addr)?;
1290        socket.start_listening()?;
1291        
1292        return Ok(UnixSeqpacketListener { fd: socket.into() });
1293    }
1294
1295    /// Returns the address the socket is listening on.
1296    pub 
1297    fn local_unix_addr(&self) -> Result<UnixSocketAddr, io::Error> 
1298    {
1299        get_unix_local_addr(&self)
1300    }
1301
1302    /// Accepts a new incoming connection to this listener.
1303    /// 
1304    /// Rustdocs: 
1305    /// > This function will block the calling thread until a new Unix connection
1306    /// > is established. When established, the corresponding [`UnixSeqpacketConn`] and
1307    /// > the remote peer's address will be returned.
1308    /// 
1309    /// [`UnixSeqpacketConn`]: UnixSeqpacketConn
1310    ///
1311    /// # Examples
1312    ///
1313    /// ```no_run
1314    /// use uds_fork::UnixSeqpacketListener;
1315    ///
1316    /// fn main() -> std::io::Result<()> 
1317    /// {
1318    ///     let listener = UnixSeqpacketListener::bind("/path/to/the/socket")?;
1319    ///
1320    ///     match listener.accept()
1321    ///     {
1322    ///         Ok((socket, addr)) => 
1323    ///             println!("Got a client: {addr:?}"),
1324    ///         Err(e) => 
1325    ///             println!("accept function failed: {e:?}"),
1326    ///     }
1327    /// 
1328    ///     return Ok(());
1329    /// }
1330    /// ```
1331    #[inline]
1332    pub 
1333    fn accept(&self)-> Result<(UnixSeqpacketConn, UnixSocketAddr), io::Error> 
1334    {
1335        self.accept_unix_addr()
1336    }
1337
1338    /// Accepts a new incoming connection to this listener.
1339    /// 
1340    /// See [Self::accept].
1341    pub 
1342    fn accept_unix_addr(&self)-> Result<(UnixSeqpacketConn, UnixSocketAddr), io::Error> 
1343    {
1344        let (socket, addr) = Socket::<SocketSeqPkt>::accept_from(&self, false)?;
1345        let conn = UnixSeqpacketConn { fd: socket.into() };
1346        
1347        return Ok((conn, addr));
1348    }
1349
1350    /// Returns the value of the `SO_ERROR` option.
1351    ///
1352    /// This might never produce any errors for listeners. It is therefore
1353    /// unlikely to be useful, but is provided for parity with
1354    /// `std::unix::net::UnixListener`.
1355    pub 
1356    fn take_error(&self) -> Result<Option<io::Error>, io::Error> 
1357    {
1358        take_error(&self)
1359    }
1360
1361    /// Creates a new file descriptor listening for the same connections.
1362    pub 
1363    fn try_clone(&self) -> Result<Self, io::Error> 
1364    {
1365        let cloned = Socket::<SocketSeqPkt>::try_clone_from(&self)?;
1366        
1367        return Ok(UnixSeqpacketListener { fd: cloned.into() });
1368    }
1369
1370    /// Sets a maximum duration to wait in a single `accept()` on this socket.
1371    ///
1372    /// `None` disables a previously set timeout.
1373    /// An error is returned if the duration is zero.
1374    ///
1375    /// # Operating System Support
1376    ///
1377    /// Only Linux appers to apply timeouts to `accept()`.  
1378    /// On macOS, FreeBSD and NetBSD, timeouts are silently ignored.  
1379    /// On Illumos setting timeouts for all unix domain sockets silently fails.
1380    ///
1381    /// On OSes where timeouts are known to not work, this function will
1382    /// return an error even if setting the timeout didn't fail.
1383    ///
1384    /// # Examples
1385    ///
1386    #[cfg_attr(any(target_os="linux", target_os="android"), doc="```")]
1387    #[cfg_attr(not(any(target_os="linux", target_os="android")), doc="```no_run")]
1388    /// # use uds_fork::{UnixSeqpacketListener, UnixSocketAddr};
1389    /// # use std::io::ErrorKind;
1390    /// # use std::time::Duration;
1391    /// #
1392    /// # let addr = UnixSocketAddr::new("@set_timeout").unwrap();
1393    /// let listener = UnixSeqpacketListener::bind_unix_addr(&addr).unwrap();
1394    /// listener.set_timeout(Some(Duration::new(0, 200_000_000))).unwrap();
1395    /// let err = listener.accept_unix_addr().unwrap_err();
1396    /// assert_eq!(err.kind(), ErrorKind::WouldBlock);
1397    /// ```
1398    pub 
1399    fn set_timeout(&self,  timeout: Option<Duration>) -> Result<(), io::Error> 
1400    {
1401        let res = set_timeout(&self, TimeoutDirection::Read, timeout);
1402
1403        #[cfg(any(
1404                target_vendor="apple", target_os="freebsd",
1405                target_os="netbsd",
1406                target_os="illumos", target_os="solaris",
1407            ))]
1408        {
1409            if res.is_ok() == true && timeout.is_some() == true
1410            {
1411                return Err(
1412                    io::Error::new(
1413                        ErrorKind::InvalidInput,
1414                        "listener timeouts are not supported on this OS"
1415                    )
1416                );
1417            }
1418        }
1419
1420        return res;
1421    }
1422
1423    /// Returns the timeout for `accept()` on this socket.
1424    ///
1425    /// `None` is returned if there is no timeout.
1426    ///
1427    /// Even if a timeout has is set, it is ignored by `accept()` on
1428    /// most operating systems except Linux.
1429    ///
1430    /// # Examples
1431    ///
1432    #[cfg_attr(any(target_os="linux", target_os="android"), doc="```")]
1433    #[cfg_attr(not(any(target_os="linux", target_os="android")), doc="```no_run")]
1434    /// # use uds_fork::{UnixSeqpacketListener, UnixSocketAddr};
1435    /// # use std::time::Duration;
1436    /// #
1437    /// # let addr = UnixSocketAddr::new("@timeout").unwrap();
1438    /// let listener = UnixSeqpacketListener::bind_unix_addr(&addr).unwrap();
1439    /// assert_eq!(listener.timeout().unwrap(), None);
1440    /// let timeout = Some(Duration::new(2, 0));
1441    /// listener.set_timeout(timeout).unwrap();
1442    /// assert_eq!(listener.timeout().unwrap(), timeout);
1443    /// ```
1444    pub 
1445    fn timeout(&self) -> Result<Option<Duration>, io::Error> 
1446    {
1447        get_timeout(&self, TimeoutDirection::Read)
1448    }
1449
1450    /// Enables or disables nonblocking-ness of [`accept_unix_addr()`](#method.accept_unix addr).
1451    ///
1452    /// The returned connnections will still be in blocking mode regardsless.
1453    ///
1454    /// Consider using the nonblocking variant of this type instead;
1455    /// this method mostly exists for feature parity with std's `UnixListener`.
1456    ///
1457    /// # Examples
1458    ///
1459    #[cfg_attr(not(target_vendor="apple"), doc="```")]
1460    #[cfg_attr(target_vendor="apple", doc="```no_run")]
1461    /// # use std::io::ErrorKind;
1462    /// # use uds_fork::{UnixSocketAddr, UnixSeqpacketListener};
1463    /// use tempfile::TempDir;
1464    /// 
1465    /// let dir = tempfile::tempdir().unwrap();
1466    /// let mut file_path = dir.path().join("nonblocking_seqpacket_listener1.socket");
1467    /// 
1468    /// let addr = UnixSocketAddr::from_path(&file_path).unwrap();
1469    /// let listener = UnixSeqpacketListener::bind_unix_addr(&addr).expect("create listener");
1470    /// listener.set_nonblocking(true).expect("enable noblocking mode");
1471    /// assert_eq!(listener.accept_unix_addr().unwrap_err().kind(), ErrorKind::WouldBlock);
1472    /// ```
1473    pub 
1474    fn set_nonblocking(&self,  nonblocking: bool) -> Result<(), io::Error> 
1475    {
1476        set_nonblocking(&self, nonblocking)
1477    }
1478
1479    /// Returns an iterator over incoming connections.
1480    /// 
1481    /// Rustdoc:
1482    /// > The iterator will never return [`None`] and will also not yield the
1483    /// > peer's [`UnixSocketAddr`] structure.
1484    /// 
1485    /// ```no_run
1486    /// use std::thread;
1487    /// use uds_fork::{UnixSeqpacketConn, UnixSeqpacketListener};
1488    ///
1489    /// fn handle_client(stream: UnixSeqpacketConn) 
1490    /// {
1491    ///     // ...
1492    /// }
1493    ///
1494    /// fn main() -> std::io::Result<()> 
1495    /// {
1496    ///     let listener = UnixSeqpacketListener::bind("/path/to/the/socket")?;
1497    ///
1498    ///     for stream in listener.incoming() 
1499    ///     {
1500    ///         match stream 
1501    ///         {
1502    ///             Ok(stream) => 
1503    ///             {
1504    ///                 thread::spawn(|| handle_client(stream));
1505    ///             },
1506    ///             Err(err) => 
1507    ///             {
1508    ///                 break;
1509    ///             }
1510    ///         }
1511    ///     }
1512    /// 
1513    ///     return Ok(());
1514    /// }
1515    /// ```
1516    pub 
1517    fn incoming(&self) -> Incoming<'_> 
1518    {
1519        Incoming { listener: self }
1520    }
1521}
1522
1523/// A rust std API.
1524/// 
1525/// From Rustdocs:
1526/// > An iterator over incoming connections to a [`UnixListener`].
1527/// >
1528/// > It will never return [`None`].
1529/// 
1530/// # Examples
1531///
1532/// ```no_run
1533/// use std::thread;
1534/// use uds_fork::{UnixSeqpacketConn, UnixSeqpacketListener};
1535///
1536/// fn handle_client(stream: UnixSeqpacketConn) {
1537///     // ...
1538/// }
1539///
1540/// fn main() -> std::io::Result<()> 
1541/// {
1542///     let listener = UnixSeqpacketListener::bind("/path/to/the/socket")?;
1543///
1544///     for stream in listener.incoming() 
1545///     {
1546///         match stream 
1547///         {
1548///             Ok(stream) => 
1549///             {
1550///                 thread::spawn(|| handle_client(stream));
1551///             }
1552///             Err(err) => 
1553///             {
1554///                 break;
1555///             }
1556///         }
1557///     }
1558///     return Ok(());
1559/// }
1560/// ```
1561#[derive(Debug)]
1562pub struct Incoming<'a> 
1563{
1564    listener: &'a UnixSeqpacketListener,
1565}
1566
1567impl<'a> Iterator for Incoming<'a> 
1568{
1569    type Item = io::Result<UnixSeqpacketConn>;
1570
1571    fn next(&mut self) -> Option<io::Result<UnixSeqpacketConn>> 
1572    {
1573        Some(self.listener.accept().map(|s| s.0))
1574    }
1575
1576    fn size_hint(&self) -> (usize, Option<usize>) 
1577    {
1578        (usize::MAX, None)
1579    }
1580}
1581
1582impl<'a> IntoIterator for &'a UnixSeqpacketListener 
1583{
1584    type Item = io::Result<UnixSeqpacketConn>;
1585    type IntoIter = Incoming<'a>;
1586
1587    fn into_iter(self) -> Incoming<'a> 
1588    {
1589        self.incoming()
1590    }
1591}
1592
1593
1594
1595/// A non-blocking unix domain sequential-packet connection.
1596///
1597/// Differs from [`uds_fork::UnixSeqpacketConn`](../struct.UnixSeqpacketConn.html)
1598/// in that all operations that send or receive data will return an `Error` of
1599/// kind `ErrorKind::WouldBlock` instead of blocking.
1600/// This is done by creating the socket as non-blocking, and not by passing
1601/// `MSG_DONTWAIT`. If creating this type from a raw file descriptor, ensure
1602/// the fd is set to nonblocking before using it through this type.
1603/// 
1604/// # Registering with Xio (xio-rs) a feature = "xio-rs"
1605/// 
1606/// A `XioEventPipe` is implemented on this function. See [UnixSeqpacketConn]
1607/// for an examples.
1608/// 
1609/// See examples below.
1610/// 
1611/// # Registering with Mio (mio) a feature = "mio"
1612/// 
1613/// A `Source` is implemented on the instance. See [UnixSeqpacketConn]
1614/// for an examples.
1615/// 
1616/// # Examples
1617///
1618/// Sending or receiving when it would block a normal socket:
1619///
1620#[cfg_attr(not(target_vendor="apple"), doc="```")]
1621#[cfg_attr(target_vendor="apple", doc="```no_run")]
1622/// use uds_fork::nonblocking::UnixSeqpacketConn;
1623/// use std::io::ErrorKind;
1624///
1625/// let (a, b) = UnixSeqpacketConn::pair().expect("create nonblocking seqpacket pair");
1626///
1627/// // trying to receive when there are no packets waiting
1628/// assert_eq!(a.recv(&mut[0]).unwrap_err().kind(), ErrorKind::WouldBlock);
1629///
1630/// // trying to send when the OS buffer for the connection is full
1631/// loop {
1632///     if let Err(error) = a.send(&[0u8; 1000]) {
1633///         assert_eq!(error.kind(), ErrorKind::WouldBlock);
1634///         break;
1635///     }
1636/// }
1637/// ```
1638//#[deprecated = "Use UnixSeqpacketListener set_nonblocking(true)!"]
1639#[derive(Debug)]
1640#[repr(transparent)]
1641pub struct NonblockingUnixSeqpacketConn 
1642{
1643    usc: UnixSeqpacketConn,
1644}
1645
1646impl From<OwnedFd> for NonblockingUnixSeqpacketConn
1647{
1648    fn from(value: OwnedFd) -> Self 
1649    {
1650        let usc = UnixSeqpacketConn::from(value);
1651        usc.set_nonblocking(true).unwrap();
1652
1653        return Self{ usc: usc };
1654    }
1655}
1656
1657impl From<NonblockingUnixSeqpacketConn> for OwnedFd
1658{
1659    fn from(value: NonblockingUnixSeqpacketConn) -> Self 
1660    {
1661        return value.usc.fd;
1662    }
1663}
1664
1665impl FromRawFd for NonblockingUnixSeqpacketConn
1666{
1667    unsafe 
1668    fn from_raw_fd(fd: RawFd) -> Self 
1669    {
1670        let usc = unsafe{ UnixSeqpacketConn::from_raw_fd(fd) };
1671        usc.set_nonblocking(true).unwrap();
1672
1673        return Self{ usc: usc };
1674    }
1675}
1676
1677impl AsRawFd for NonblockingUnixSeqpacketConn
1678{
1679    fn as_raw_fd(&self) -> RawFd 
1680    {
1681        self.usc.as_raw_fd()
1682    }
1683}
1684impl IntoRawFd for NonblockingUnixSeqpacketConn
1685{
1686    fn into_raw_fd(self) -> RawFd 
1687    {
1688        self.usc.into_raw_fd()
1689    }
1690}
1691
1692impl AsFd for NonblockingUnixSeqpacketConn
1693{
1694    fn as_fd(&self) -> BorrowedFd<'_> 
1695    {
1696        self.usc.as_fd()
1697    }
1698}
1699
1700impl Deref for NonblockingUnixSeqpacketConn
1701{
1702    type Target = UnixSeqpacketConn;
1703
1704    fn deref(&self) -> &Self::Target 
1705    {
1706        &self.usc
1707    }
1708}
1709
1710impl DerefMut for NonblockingUnixSeqpacketConn
1711{
1712    fn deref_mut(&mut self) -> &mut Self::Target 
1713    {
1714        &mut self.usc
1715    }
1716}
1717
1718
1719#[cfg(feature = "mio")]
1720pub mod mio_non_blk_conn_enabled
1721{
1722    use std::io;
1723
1724    use mio::event::Source;
1725    use super::NonblockingUnixSeqpacketConn;
1726
1727    impl Source for NonblockingUnixSeqpacketConn
1728    {
1729        fn register(
1730            &mut self,
1731            registry: &mio::Registry,
1732            token: mio::Token,
1733            interests: mio::Interest,
1734        ) -> io::Result<()> 
1735        {
1736            self.usc.register(registry, token, interests)
1737        }
1738    
1739        fn reregister(
1740            &mut self,
1741            registry: &mio::Registry,
1742            token: mio::Token,
1743            interests: mio::Interest,
1744        ) -> io::Result<()> 
1745        {
1746            self.usc.reregister(registry, token, interests)
1747        }
1748    
1749        fn deregister(&mut self, registry: &mio::Registry) -> io::Result<()> 
1750        {
1751            self.usc.deregister(registry)
1752        }
1753    }
1754}
1755
1756#[cfg(feature = "xio-rs")]
1757pub mod xio_non_blk_conn_enabled
1758{
1759    use xio_rs::{EsInterfaceRegistry, XioChannel, XioEventPipe, XioEventUid, XioResult, event_registry::XioRegistry};
1760
1761    use super::NonblockingUnixSeqpacketConn;
1762
1763    impl<ESSR: EsInterfaceRegistry> XioEventPipe<ESSR, Self> for NonblockingUnixSeqpacketConn
1764    {
1765        fn connect_event_pipe(&mut self, ess: &XioRegistry<ESSR>, ev_uid: XioEventUid, channel: XioChannel) -> XioResult<()> 
1766        {
1767            self.usc.connect_event_pipe(ess, ev_uid, channel)
1768        }
1769    
1770        fn modify_event_pipe(&mut self, ess: &XioRegistry<ESSR>, ev_uid: XioEventUid, channel: XioChannel) -> XioResult<()> 
1771        {
1772            self.usc.modify_event_pipe(ess, ev_uid, channel)
1773        }
1774    
1775        fn disconnect_event_pipe(&mut self, ess: &XioRegistry<ESSR>) -> XioResult<()> 
1776        {
1777            self.usc.disconnect_event_pipe(ess)
1778        }
1779    }
1780}
1781
1782// can't Deref<Target=UnixSeqpacketConn> because that would include try_clone()
1783// and later set_(read|write)_timeout()
1784impl NonblockingUnixSeqpacketConn 
1785{
1786    /// Connects to an unix seqpacket server listening at `path`.
1787    ///
1788    /// This is a wrapper around [`connect_unix_addr()`](#method.connect_unix_addr)
1789    /// for convenience and compatibility with std.
1790    pub 
1791    fn connect<P: AsRef<Path>>(path: P) -> Result<Self, io::Error> 
1792    {
1793        let addr = UnixSocketAddr::from_path(&path)?;
1794
1795        return Self::connect_unix_addr(&addr);
1796    }
1797
1798    /// Connects to an unix seqpacket server listening at `addr`.
1799    pub 
1800    fn connect_unix_addr(addr: &UnixSocketAddr) -> Result<Self, io::Error> 
1801    {
1802        let socket = Socket::<SocketSeqPkt>::new(true)?;
1803        socket.set_unix_peer_addr(addr)?;
1804        
1805        return Ok(
1806            NonblockingUnixSeqpacketConn 
1807            {
1808                usc: UnixSeqpacketConn { fd: socket.into() }
1809            }
1810        );
1811    }
1812    
1813    /// Binds to an address before connecting to a listening seqpacet socket.
1814    pub 
1815    fn connect_from_to_unix_addr(from: &UnixSocketAddr,  to: &UnixSocketAddr) -> Result<Self, io::Error> 
1816    {
1817        let socket = Socket::<SocketSeqPkt>::new(true)?;
1818        socket.set_unix_local_addr(from)?;
1819        socket.set_unix_peer_addr(to)?;
1820        
1821        return Ok(
1822            NonblockingUnixSeqpacketConn 
1823            {
1824                usc: UnixSeqpacketConn { fd: socket.into() }
1825            }
1826        );
1827    }
1828
1829    /// Creates a pair of unix-domain seqpacket conneections connected to each other.
1830    ///
1831    /// # Examples
1832    ///
1833    #[cfg_attr(not(target_vendor="apple"), doc="```")]
1834    #[cfg_attr(target_vendor="apple", doc="```no_run")]
1835    /// let (a, b) = uds_fork::UnixSeqpacketConn::pair().unwrap();
1836    /// assert!(a.local_unix_addr().unwrap().is_unnamed());
1837    /// assert!(b.local_unix_addr().unwrap().is_unnamed());
1838    ///
1839    /// a.send(b"hello").unwrap();
1840    /// b.recv(&mut[0; 20]).unwrap();
1841    /// ```
1842    pub 
1843    fn pair() -> Result<(Self, Self), io::Error> 
1844    {
1845        let pair = Socket::<SocketSeqPkt>::pair(true)?;
1846        
1847        return Ok(
1848            (
1849                Self{ usc: UnixSeqpacketConn { fd: pair.0.into() } },
1850                Self{ usc: UnixSeqpacketConn { fd: pair.1.into() } },
1851            )
1852        );
1853    }
1854
1855    pub 
1856    fn try_clone(&self) -> Result<Self, io::Error> 
1857    {
1858        let cloned = Socket::<SocketSeqPkt>::try_clone_from(self)?;
1859
1860        return Ok(
1861            NonblockingUnixSeqpacketConn 
1862            {
1863                usc: UnixSeqpacketConn { fd: cloned.into() }
1864            }
1865        );
1866    }
1867}
1868
1869impl io::Read for NonblockingUnixSeqpacketConn
1870{
1871    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> 
1872    {
1873        self.recv(buf)
1874    }
1875
1876    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> 
1877    {
1878        self.recv_vectored(bufs).map(|(n, _)| n)
1879    }
1880}
1881
1882impl<'a> io::Read for &'a NonblockingUnixSeqpacketConn
1883{
1884    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> 
1885    {
1886        self.recv(buf)
1887    }
1888
1889    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> 
1890    {
1891        self.recv_vectored(bufs).map(|(n, _)| n)
1892    }
1893}
1894
1895impl io::Write for NonblockingUnixSeqpacketConn
1896{
1897    fn write(&mut self, buf: &[u8]) -> io::Result<usize> 
1898    {
1899        self.send(buf)
1900    }
1901
1902    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> 
1903    {
1904        self.send_vectored(bufs)
1905    }
1906
1907    fn flush(&mut self) -> io::Result<()> 
1908    {
1909        todo!()
1910    }
1911}
1912
1913
1914/// A non-blocking unix domain listener for sequential-packet connections.
1915///
1916/// Differs from [`UnixSeqpacketListener`](../struct.UnixSeqpacketListener.html)
1917/// in that [`accept()`](struct.NonblockingUnixSeqpacketListener.html#method.accept)
1918/// returns non-blocking [connection sockets](struct.NonblockingUnixSeqpacketConn.html)
1919/// and doesn't block if no client `connect()`ions are pending.
1920///
1921/// # Registering with Xio (xio-rs) a feature = "xio-rs"
1922/// 
1923/// A `XioEventPipe` is implemented on this function. See [UnixSeqpacketListener]
1924/// for an examples.
1925/// 
1926/// See examples below.
1927/// 
1928/// # Registering with Mio (mio) a feature = "mio"
1929/// 
1930/// A `Source` is implemented on the instance. See [UnixSeqpacketListener]
1931/// for an examples.
1932///
1933/// # Examples
1934///
1935#[cfg_attr(not(target_vendor="apple"), doc="```")]
1936#[cfg_attr(target_vendor="apple", doc="```no_run")]
1937/// use uds_fork::nonblocking::{UnixSeqpacketListener, UnixSeqpacketConn};
1938/// use tempfile::TempDir;
1939/// use std::io::ErrorKind;
1940///
1941/// let dir = tempfile::tempdir().unwrap();
1942/// let mut file_path = dir.path().join("nonblocking_seqpacket_listener2.socket");
1943/// 
1944/// let listener = UnixSeqpacketListener::bind(&file_path)
1945///     .expect("Cannot create nonblocking seqpacket listener");
1946///
1947/// // doesn't block if no connections are waiting:
1948/// assert_eq!(listener.accept_unix_addr().unwrap_err().kind(), ErrorKind::WouldBlock);
1949///
1950/// // returned connections are nonblocking:
1951/// let _client = UnixSeqpacketConn::connect(&file_path).unwrap();
1952/// let (conn, _addr) = listener.accept_unix_addr().unwrap();
1953/// assert_eq!(conn.recv(&mut[0u8; 20]).unwrap_err().kind(), ErrorKind::WouldBlock);
1954/// ```
1955#[derive(Debug)]
1956#[repr(transparent)]
1957pub struct NonblockingUnixSeqpacketListener 
1958{
1959    usl: UnixSeqpacketListener,
1960}
1961
1962impl From<OwnedFd> for NonblockingUnixSeqpacketListener
1963{
1964    fn from(ofd: OwnedFd) -> Self 
1965    {
1966        let usl = UnixSeqpacketListener::from(ofd);
1967        usl.set_nonblocking(true).unwrap();
1968
1969        return Self{ usl };
1970    }
1971}
1972
1973impl FromRawFd for NonblockingUnixSeqpacketListener
1974{
1975    unsafe 
1976    fn from_raw_fd(fd: RawFd) -> Self 
1977    {
1978        let usl = unsafe{ UnixSeqpacketListener::from_raw_fd(fd) };
1979        usl.set_nonblocking(true).unwrap();
1980
1981        return Self{ usl };
1982    }
1983}
1984
1985
1986impl From<NonblockingUnixSeqpacketListener> for OwnedFd
1987{
1988    fn from(value: NonblockingUnixSeqpacketListener) -> Self 
1989    {
1990        return value.usl.fd;
1991    }
1992}
1993
1994
1995impl AsRawFd for NonblockingUnixSeqpacketListener
1996{
1997    fn as_raw_fd(&self) -> RawFd 
1998    {
1999        self.usl.as_raw_fd()
2000    }
2001}
2002
2003impl IntoRawFd for NonblockingUnixSeqpacketListener
2004{
2005    fn into_raw_fd(self) -> RawFd 
2006    {
2007        self.usl.into_raw_fd()
2008    }
2009}
2010
2011impl AsFd for NonblockingUnixSeqpacketListener
2012{
2013    fn as_fd(&self) -> BorrowedFd<'_> 
2014    {
2015        self.usl.as_fd()
2016    }
2017}
2018
2019
2020impl Deref for NonblockingUnixSeqpacketListener
2021{
2022    type Target = UnixSeqpacketListener;
2023
2024    fn deref(&self) -> &Self::Target 
2025    {
2026        &self.usl
2027    }
2028}
2029
2030impl DerefMut for NonblockingUnixSeqpacketListener
2031{
2032    fn deref_mut(&mut self) -> &mut Self::Target 
2033    {
2034        &mut self.usl
2035    }
2036}
2037
2038impl NonblockingUnixSeqpacketListener 
2039{
2040    /// Creates a socket that listens for seqpacket connections on the specified socket file.
2041    pub 
2042    fn bind<P: AsRef<Path>>(path: P) -> Result<Self, io::Error> 
2043    {
2044        let addr = UnixSocketAddr::from_path(&path)?;
2045
2046        return Self::bind_unix_addr(&addr);
2047    }
2048
2049    /// Creates a socket that listens for seqpacket connections on the specified address.
2050    pub 
2051    fn bind_unix_addr(addr: &UnixSocketAddr) -> Result<Self, io::Error> 
2052    {
2053        let socket = Socket::<SocketSeqPkt>::new(true)?;
2054        socket.set_unix_local_addr(addr)?;
2055        socket.start_listening()?;
2056
2057        return Ok( Self{ usl: UnixSeqpacketListener{ fd: socket.into() }} );
2058    }
2059
2060    /// Accepts a non-blocking connection, non-blockingly.
2061    ///
2062    /// # Examples
2063    ///
2064    /// Doesn't block if no connections are waiting:
2065    ///
2066    #[cfg_attr(not(target_vendor="apple"), doc="```")]
2067    #[cfg_attr(target_vendor="apple", doc="```no_run")]
2068    /// # use uds_fork::nonblocking::UnixSeqpacketListener;
2069    /// # use std::io::ErrorKind;
2070    /// # use tempfile::TempDir;
2071    /// 
2072    /// let dir = tempfile::tempdir().unwrap();
2073    /// let mut file_path = dir.path().join("nonblocking_seqpacket_listener3.socket");
2074    /// 
2075    /// let listener = UnixSeqpacketListener::bind(&file_path)
2076    ///     .expect("Cannot create nonblocking seqpacket listener");
2077    /// assert_eq!(listener.accept_unix_addr().unwrap_err().kind(), ErrorKind::WouldBlock);
2078    /// ```
2079    pub 
2080    fn accept_unix_addr(&self) -> Result<(NonblockingUnixSeqpacketConn, UnixSocketAddr), io::Error> 
2081    {
2082        let (socket, addr) = Socket::<SocketSeqPkt>::accept_from(&self, true)?;
2083        let conn = NonblockingUnixSeqpacketConn { usc: UnixSeqpacketConn{ fd: socket.into() }};
2084        
2085        return Ok((conn, addr));
2086    }
2087}
2088
2089
2090
2091#[cfg(feature = "mio")]
2092pub mod mio_non_blk_listener_enabled
2093{
2094    use std::{io, os::fd::AsRawFd};
2095
2096    use mio::{event::Source, unix::SourceFd};
2097    use super::NonblockingUnixSeqpacketListener;
2098
2099    impl Source for NonblockingUnixSeqpacketListener
2100    {
2101        fn register(
2102            &mut self,
2103            registry: &mio::Registry,
2104            token: mio::Token,
2105            interests: mio::Interest,
2106        ) -> io::Result<()> 
2107        {
2108            self.usl.register(registry, token, interests)
2109        }
2110    
2111        fn reregister(
2112            &mut self,
2113            registry: &mio::Registry,
2114            token: mio::Token,
2115            interests: mio::Interest,
2116        ) -> io::Result<()> 
2117        {
2118            self.usl.reregister(registry, token, interests)
2119        }
2120    
2121        fn deregister(&mut self, registry: &mio::Registry) -> io::Result<()> 
2122        {
2123            self.usl.deregister(registry)
2124        }
2125    }
2126}
2127
2128#[cfg(feature = "xio-rs")]
2129pub mod xio_non_blk_listener_enabled
2130{
2131    use xio_rs::{EsInterfaceRegistry, XioChannel, XioEventPipe, XioEventUid, XioResult, event_registry::XioRegistry};
2132
2133    use super::NonblockingUnixSeqpacketListener;
2134
2135    impl<ESSR: EsInterfaceRegistry> XioEventPipe<ESSR, Self> for NonblockingUnixSeqpacketListener
2136    {
2137        fn connect_event_pipe(&mut self, ess: &XioRegistry<ESSR>, ev_uid: XioEventUid, channel: XioChannel) -> XioResult<()> 
2138        {
2139 
2140            self.usl.connect_event_pipe(ess, ev_uid, channel)
2141        }
2142    
2143        fn modify_event_pipe(&mut self, ess: &XioRegistry<ESSR>, ev_uid: XioEventUid, channel: XioChannel) -> XioResult<()> 
2144        {
2145            self.usl.modify_event_pipe(ess, ev_uid, channel)
2146        }
2147    
2148        fn disconnect_event_pipe(&mut self, ess: &XioRegistry<ESSR>) -> XioResult<()> 
2149        {
2150            self.usl.disconnect_event_pipe(ess)
2151        }
2152    }
2153}