Skip to main content

uds_fork/
seqpacket.rs

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