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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
use crate::zero_ok;
use std::{
io,
mem::{size_of, MaybeUninit},
os::unix::io::{AsRawFd, RawFd},
};
#[derive(Debug, Clone, Copy)]
#[repr(i32)]
pub enum SocketType {
Stream = libc::SOCK_STREAM,
Datagram = libc::SOCK_DGRAM,
SeqPacket = libc::SOCK_SEQPACKET,
Raw = libc::SOCK_RAW,
Rdm = libc::SOCK_RDM,
}
#[inline]
pub fn socket_type<Fd: AsRawFd>(fd: &Fd) -> io::Result<SocketType> {
let fd = fd.as_raw_fd();
unsafe { _socket_type(fd) }
}
unsafe fn _socket_type(fd: RawFd) -> io::Result<SocketType> {
let mut buffer = MaybeUninit::<SocketType>::uninit();
let mut out_len = size_of::<SocketType>() as libc::socklen_t;
zero_ok(libc::getsockopt(
fd,
libc::SOL_SOCKET,
libc::SO_TYPE,
buffer.as_mut_ptr() as *mut libc::c_void,
&mut out_len,
))?;
assert_eq!(
out_len as usize,
size_of::<SocketType>(),
"unexpected SocketType size"
);
Ok(buffer.assume_init())
}