Skip to main content

accept4

Function accept4 

Source
pub unsafe fn accept4(
    sockfd: i32,
    addr: Option<*mut sockaddr_t>,
    addrlen: Option<&mut socklen_t>,
    flags: i32,
) -> Result<i32, Errno>
Expand description

Accept a connection on a socket.

ยงExamples

use nc::Errno;
use std::mem::{size_of, transmute};
use std::thread;

const SERVER_PORT: u16 = 18083;

#[must_use]
#[inline]
const fn htons(host: u16) -> u16 {
    host.to_be()
}

fn main() -> Result<(), Errno> {
    let listen_fd = unsafe { nc::socket(nc::AF_INET, nc::SOCK_STREAM, 0)? };
    println!("listen fd: {listen_fd}");

    let addr = nc::sockaddr_in_t {
        sin_family: nc::AF_INET as nc::sa_family_t,
        sin_port: htons(SERVER_PORT),
        sin_addr: nc::in_addr_t {
            s_addr: nc::INADDR_ANY as u32,
        },
        ..Default::default()
    };
    println!("addr: {addr:?}");

    let ret = unsafe {
        let addr_alias = transmute::<&nc::sockaddr_in_t, &nc::sockaddr_t>(&addr);
        nc::bind(listen_fd, addr_alias, size_of::<nc::sockaddr_in_t>() as u32)
    };
    assert!(ret.is_ok());

    // Start worker thread
    thread::spawn(|| {
        println!("worker thread started");
        let socket_fd = unsafe { nc::socket(nc::AF_INET, nc::SOCK_STREAM, 0) };
        assert!(socket_fd.is_ok());
        if let Ok(socket_fd) = socket_fd {
            let addr = nc::sockaddr_in_t {
                sin_family: nc::AF_INET as nc::sa_family_t,
                sin_port: htons(SERVER_PORT),
                sin_addr: nc::in_addr_t {
                    s_addr: nc::INADDR_ANY as u32,
                },
                ..Default::default()
            };
            unsafe {
                let addr_alias = transmute::<&nc::sockaddr_in_t, &nc::sockaddr_t>(&addr);
                let ret = nc::connect(socket_fd, addr_alias, size_of::<nc::sockaddr_in_t>() as u32);
                assert_eq!(ret, Ok(()));
            }
        } else {
            eprintln!("Failed to create socket");
        }
    });

    unsafe {
        nc::listen(listen_fd, nc::SOCK_STREAM)?;
    }

    let mut conn_addr = nc::sockaddr_in_t::default();
    let mut conn_addr_len: nc::socklen_t = 0;
    let conn_fd = unsafe {
        nc::accept4(
            listen_fd,
            Some(&mut conn_addr as *mut nc::sockaddr_in_t as *mut nc::sockaddr_t),
            Some(&mut conn_addr_len),
            nc::SOCK_CLOEXEC,
        )?
    };
    println!("conn_fd: {conn_fd}");

    unsafe {
        nc::close(listen_fd)?;
    }

    Ok(())
}
Examples found in repository?
examples/socket.rs (line 65)
17fn main() -> Result<(), Errno> {
18    let listen_fd = unsafe { nc::socket(nc::AF_INET, nc::SOCK_STREAM, 0)? };
19    println!("listen fd: {listen_fd}");
20
21    let addr = nc::sockaddr_in_t {
22        sin_family: nc::AF_INET as nc::sa_family_t,
23        sin_port: htons(SERVER_PORT),
24        sin_addr: nc::in_addr_t {
25            s_addr: nc::INADDR_ANY as u32,
26        },
27        ..Default::default()
28    };
29    println!("addr: {addr:?}");
30
31    let ret = unsafe {
32        let addr_alias = transmute::<&nc::sockaddr_in_t, &nc::sockaddr_t>(&addr);
33        nc::bind(listen_fd, addr_alias, size_of::<nc::sockaddr_in_t>() as u32)
34    };
35    assert!(ret.is_ok());
36
37    // Start worker thread
38    thread::spawn(|| {
39        println!("worker thread started");
40        let socket_fd = unsafe { nc::socket(nc::AF_INET, nc::SOCK_STREAM, 0) };
41        assert!(socket_fd.is_ok());
42        if let Ok(socket_fd) = socket_fd {
43            let addr = nc::sockaddr_in_t {
44                sin_family: nc::AF_INET as nc::sa_family_t,
45                sin_port: htons(SERVER_PORT),
46                sin_addr: nc::in_addr_t {
47                    s_addr: nc::INADDR_ANY as u32,
48                },
49                ..Default::default()
50            };
51            unsafe {
52                let addr_alias = (&addr as *const nc::sockaddr_in_t).cast::<nc::sockaddr_t>();
53                let ret = nc::connect(socket_fd, addr_alias, size_of::<nc::sockaddr_in_t>() as u32);
54                assert_eq!(ret, Ok(()));
55            }
56        } else {
57            eprintln!("Failed to create socket");
58        }
59    });
60
61    unsafe {
62        nc::listen(listen_fd, nc::SOCK_STREAM)?;
63    }
64
65    let conn_fd = unsafe { nc::accept4(listen_fd, None, None, nc::SOCK_CLOEXEC)? };
66    println!("conn_fd: {conn_fd}");
67
68    unsafe {
69        nc::close(listen_fd)?;
70    }
71
72    Ok(())
73}