1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
use crate::from_success_code;
use std::io::Result;
use std::os::unix::prelude::*;

#[derive(Debug, Clone, Copy)]
#[repr(i32)]
pub enum SockType {
    Stream = libc::SOCK_STREAM,
    Datagram = libc::SOCK_DGRAM,
    SeqPacket = libc::SOCK_SEQPACKET,
    Raw = libc::SOCK_RAW,
    Rdm = libc::SOCK_RDM,
}

pub unsafe fn get_socket_type(fd: RawFd) -> Result<SockType> {
    use std::mem::{self, MaybeUninit};
    let mut buffer = MaybeUninit::<SockType>::zeroed().assume_init();
    let mut out_len = mem::size_of::<SockType>() as libc::socklen_t;
    from_success_code(libc::getsockopt(
        fd,
        libc::SOL_SOCKET,
        libc::SO_TYPE,
        &mut buffer as *mut SockType as *mut _,
        &mut out_len,
    ))?;
    assert_eq!(
        out_len as usize,
        mem::size_of::<SockType>(),
        "invalid SockType value"
    );
    Ok(buffer)
}