use crate::error::Error;
use crate::syscall;
use crate::types::{RawFd, SockAddrIn};
use core::mem;
pub struct Socket {
fd: RawFd,
}
impl Socket {
pub fn new(domain: i32, sock_type: i32, protocol: i32) -> Result<Self, Error> {
let fd = syscall::socket(domain, sock_type, protocol)? as RawFd;
Ok(Self { fd })
}
#[inline]
pub fn fd(&self) -> RawFd {
self.fd
}
#[inline]
pub fn into_fd(self) -> RawFd {
let fd = self.fd;
mem::forget(self);
fd
}
pub fn bind(&self, addr: &SockAddrIn) -> Result<(), Error> {
syscall::bind(
self.fd as usize,
(addr as *const SockAddrIn).cast(),
mem::size_of::<SockAddrIn>() as u32,
)
}
pub fn listen(&self, backlog: i32) -> Result<(), Error> {
syscall::listen(self.fd as usize, backlog)
}
pub fn set_option<T: Sized>(&self, level: i32, optname: i32, value: &T) -> Result<(), Error> {
syscall::setsockopt(
self.fd as usize,
level,
optname,
(value as *const T).cast(),
mem::size_of::<T>() as u32,
)
}
pub fn local_addr(&self) -> Result<SockAddrIn, Error> {
let mut addr = SockAddrIn::default();
let mut len = mem::size_of::<SockAddrIn>() as u32;
syscall::getsockname(
self.fd as usize,
(&raw mut addr).cast(),
&raw mut len,
)?;
Ok(addr)
}
}
impl Drop for Socket {
fn drop(&mut self) {
let _ = syscall::close(self.fd as usize);
}
}