mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-23 01:13:23 +00:00
Refactor unix stream socket implementation
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
93429ae2c9
commit
3f15bcaf5d
@ -1,50 +1,99 @@
|
||||
use core::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
use crate::fs::utils::{IoEvents, Pollee, Poller};
|
||||
use crate::net::socket::unix::addr::UnixSocketAddr;
|
||||
use crate::fs::fs_resolver::{split_path, FsPath};
|
||||
use crate::fs::utils::{Dentry, InodeMode, InodeType, IoEvents, Pollee, Poller};
|
||||
use crate::net::socket::unix::addr::{UnixSocketAddr, UnixSocketAddrBound};
|
||||
use crate::prelude::*;
|
||||
|
||||
pub struct Init {
|
||||
use super::connected::Connected;
|
||||
use super::endpoint::Endpoint;
|
||||
use super::listener::push_incoming;
|
||||
|
||||
pub(super) struct Init {
|
||||
is_nonblocking: AtomicBool,
|
||||
bind_addr: Option<UnixSocketAddr>,
|
||||
addr: Mutex<Option<UnixSocketAddrBound>>,
|
||||
pollee: Pollee,
|
||||
}
|
||||
|
||||
impl Init {
|
||||
pub fn new(is_nonblocking: bool) -> Self {
|
||||
pub(super) fn new(is_nonblocking: bool) -> Self {
|
||||
Self {
|
||||
is_nonblocking: AtomicBool::new(is_nonblocking),
|
||||
bind_addr: None,
|
||||
addr: Mutex::new(None),
|
||||
pollee: Pollee::new(IoEvents::empty()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bind(&mut self, mut addr: UnixSocketAddr) -> Result<()> {
|
||||
if self.bind_addr.is_some() {
|
||||
pub(super) fn bind(&self, addr_to_bind: &UnixSocketAddr) -> Result<()> {
|
||||
let mut addr = self.addr.lock();
|
||||
if addr.is_some() {
|
||||
return_errno_with_message!(Errno::EINVAL, "the socket is already bound");
|
||||
}
|
||||
addr.create_file_and_bind()?;
|
||||
self.bind_addr = Some(addr);
|
||||
|
||||
let bound_addr = match addr_to_bind {
|
||||
UnixSocketAddr::Abstract(_) => todo!(),
|
||||
UnixSocketAddr::Path(path) => {
|
||||
let dentry = create_socket_file(path)?;
|
||||
UnixSocketAddrBound::Path(dentry)
|
||||
}
|
||||
};
|
||||
|
||||
*addr = Some(bound_addr);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn is_bound(&self) -> bool {
|
||||
self.bind_addr.is_none()
|
||||
pub(super) fn connect(&self, remote_addr: &UnixSocketAddrBound) -> Result<Connected> {
|
||||
let addr = self.addr();
|
||||
|
||||
if let Some(ref addr) = addr {
|
||||
if *addr == *remote_addr {
|
||||
return_errno_with_message!(Errno::EINVAL, "try to connect to self is invalid");
|
||||
}
|
||||
}
|
||||
|
||||
let (this_end, remote_end) = Endpoint::new_pair(self.is_nonblocking())?;
|
||||
remote_end.set_addr(remote_addr.clone());
|
||||
if let Some(addr) = addr {
|
||||
this_end.set_addr(addr.clone());
|
||||
};
|
||||
|
||||
push_incoming(remote_addr, remote_end)?;
|
||||
Ok(Connected::new(this_end))
|
||||
}
|
||||
|
||||
pub fn bound_addr(&self) -> Option<&UnixSocketAddr> {
|
||||
self.bind_addr.as_ref()
|
||||
pub(super) fn is_bound(&self) -> bool {
|
||||
self.addr.lock().is_some()
|
||||
}
|
||||
|
||||
pub fn is_nonblocking(&self) -> bool {
|
||||
pub(super) fn addr(&self) -> Option<UnixSocketAddrBound> {
|
||||
self.addr.lock().clone()
|
||||
}
|
||||
|
||||
pub(super) fn is_nonblocking(&self) -> bool {
|
||||
self.is_nonblocking.load(Ordering::Acquire)
|
||||
}
|
||||
|
||||
pub fn set_nonblocking(&self, is_nonblocking: bool) {
|
||||
pub(super) fn set_nonblocking(&self, is_nonblocking: bool) {
|
||||
self.is_nonblocking.store(is_nonblocking, Ordering::Release);
|
||||
}
|
||||
|
||||
pub fn poll(&self, mask: IoEvents, poller: Option<&Poller>) -> IoEvents {
|
||||
pub(super) fn poll(&self, mask: IoEvents, poller: Option<&Poller>) -> IoEvents {
|
||||
self.pollee.poll(mask, poller)
|
||||
}
|
||||
}
|
||||
|
||||
fn create_socket_file(path: &str) -> Result<Arc<Dentry>> {
|
||||
let (parent_pathname, file_name) = split_path(path);
|
||||
let parent = {
|
||||
let current = current!();
|
||||
let fs = current.fs().read();
|
||||
let parent_path = FsPath::try_from(parent_pathname)?;
|
||||
fs.lookup(&parent_path)?
|
||||
};
|
||||
let dentry = parent.create(
|
||||
file_name,
|
||||
InodeType::Socket,
|
||||
InodeMode::S_IRUSR | InodeMode::S_IWUSR,
|
||||
)?;
|
||||
Ok(dentry)
|
||||
}
|
||||
|
Reference in New Issue
Block a user