bitcoin-sock 0.1.19

Low-level, cross-platform RAII wrapper and utilities for raw OS sockets, mirroring Bitcoin Core networking semantics (send/recv, timeouts, readiness, error classification).
// ---------------- [ File: bitcoin-sock/src/lifetime.rs ]
crate::ix!();

#[cfg(test)]
mod sock_lifetime_spec {
    use super::*;

    #[cfg(unix)]
    fn make_socket_pair() -> (libc::c_int, libc::c_int) {
        let mut sv = [-1; 2];
        let ret =
            unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, sv.as_mut_ptr()) };
        assert_eq!(ret, 0, "socketpair() failed");
        (sv[0], sv[1])
    }

    #[traced_test]
    fn reset_closes_descriptor() {

        serialize_fds!();

        #[cfg(unix)]
        {
            use libc::read;

            let (a, b) = make_socket_pair();
            let mut sock = Sock::from(a);

            sock.reset();
            assert_eq!(sock.get(), INVALID_SOCKET);

            // The peer must now see EOF immediately.
            let mut buf = [0u8; 1];
            let ret = unsafe { read(b, buf.as_mut_ptr() as *mut _, 1) };
            assert_eq!(ret, 0, "peer should see EOF after close");
        }

        info!("reset_closes_descriptor passed");
    }

    #[traced_test]
    fn release_transfers_ownership() {
        serialize_fds!();
        #[cfg(unix)]
        {
            use libc::{fcntl, F_GETFD};

            let (a, _b) = make_socket_pair();
            let mut sock = Sock::from(a);

            let raw = sock.release();
            assert_eq!(sock.get(), INVALID_SOCKET);
            assert_ne!(raw, INVALID_SOCKET);

            let ret = unsafe { fcntl(raw, F_GETFD) };
            assert_ne!(ret, -1, "descriptor should still be open");
        }

        info!("release_transfers_ownership passed");
    }
}