use std::{
io,
net::SocketAddr,
sync::atomic::{AtomicBool, Ordering},
};
use crate::{
api::resource::Resource, net_utils::std_socketaddr_into_libc,
typed_op::TypedOp,
};
pub struct Connect {
res: Resource,
addr: libc::sockaddr_storage,
len: libc::socklen_t,
connect_called: AtomicBool,
}
assert_op_max_size!(Connect);
impl Connect {
pub(crate) fn new(res: Resource, addr: SocketAddr) -> Self {
let addr = std_socketaddr_into_libc(addr);
let len = if addr.ss_family == libc::AF_INET as libc::sa_family_t {
std::mem::size_of::<libc::sockaddr_in>()
} else if addr.ss_family == libc::AF_INET6 as libc::sa_family_t {
std::mem::size_of::<libc::sockaddr_in6>()
} else {
std::mem::size_of::<libc::sockaddr_storage>()
} as libc::socklen_t;
Self { res, addr, len, connect_called: AtomicBool::new(false) }
}
}
impl TypedOp for Connect {
type Result = io::Result<()>;
fn into_op(&mut self) -> crate::op::Op {
let connect_called = self.connect_called.load(Ordering::Relaxed);
crate::op::Op::Connect {
fd: self.res.clone(),
addr: &self.addr as *const _,
len: self.len,
connect_called,
}
}
fn extract_result(self, res: isize) -> Self::Result {
if res < 0 {
Err(io::Error::from_raw_os_error((-res) as i32))
} else {
Ok(())
}
}
}