Merge branch 'feature/support-af-unix-sockets' into 'master'
Support AF_UNIX sockets See merge request redox-os/ipcd!2
This commit is contained in:
+54
-2
@@ -40,11 +40,16 @@ impl Default for Connection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct NullFile {
|
||||||
|
pub flags: usize,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Handle {
|
pub struct Handle {
|
||||||
id: usize,
|
id: usize,
|
||||||
flags: usize,
|
flags: usize,
|
||||||
extra: Extra
|
extra: Extra,
|
||||||
|
path: Option<String>,
|
||||||
}
|
}
|
||||||
impl Handle {
|
impl Handle {
|
||||||
/// Duplicate this listener handle into one that is linked to the
|
/// Duplicate this listener handle into one that is linked to the
|
||||||
@@ -92,6 +97,7 @@ impl Handle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct ChanScheme {
|
pub struct ChanScheme {
|
||||||
|
nulls: HashMap<usize, NullFile>,
|
||||||
handles: HashMap<usize, Handle>,
|
handles: HashMap<usize, Handle>,
|
||||||
listeners: HashMap<String, usize>,
|
listeners: HashMap<String, usize>,
|
||||||
next_id: usize,
|
next_id: usize,
|
||||||
@@ -100,6 +106,7 @@ pub struct ChanScheme {
|
|||||||
impl ChanScheme {
|
impl ChanScheme {
|
||||||
pub fn new() -> io::Result<Self> {
|
pub fn new() -> io::Result<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
nulls: HashMap::new(),
|
||||||
handles: HashMap::new(),
|
handles: HashMap::new(),
|
||||||
listeners: HashMap::new(),
|
listeners: HashMap::new(),
|
||||||
next_id: 0,
|
next_id: 0,
|
||||||
@@ -124,6 +131,20 @@ impl SchemeBlockMut for ChanScheme {
|
|||||||
let path = ::std::str::from_utf8(path).or(Err(Error::new(EPERM)))?;
|
let path = ::std::str::from_utf8(path).or(Err(Error::new(EPERM)))?;
|
||||||
|
|
||||||
let new_id = self.next_id;
|
let new_id = self.next_id;
|
||||||
|
|
||||||
|
if path.is_empty() {
|
||||||
|
let null = NullFile {
|
||||||
|
flags: flags,
|
||||||
|
};
|
||||||
|
|
||||||
|
let id = new_id;
|
||||||
|
|
||||||
|
self.nulls.insert(id, null);
|
||||||
|
self.next_id += 1;
|
||||||
|
|
||||||
|
return Ok(Some(id));
|
||||||
|
}
|
||||||
|
|
||||||
let mut new = Handle::default();
|
let mut new = Handle::default();
|
||||||
new.flags = flags;
|
new.flags = flags;
|
||||||
|
|
||||||
@@ -154,15 +175,23 @@ impl SchemeBlockMut for ChanScheme {
|
|||||||
Ok(Some(new_id))
|
Ok(Some(new_id))
|
||||||
}
|
}
|
||||||
fn dup(&mut self, id: usize, buf: &[u8]) -> Result<Option<usize>> {
|
fn dup(&mut self, id: usize, buf: &[u8]) -> Result<Option<usize>> {
|
||||||
|
if let Some(flags) = self.nulls
|
||||||
|
.get(&id)
|
||||||
|
.map(|null| null.flags)
|
||||||
|
{
|
||||||
|
return self.open(buf, flags, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
match buf {
|
match buf {
|
||||||
b"listen" => {
|
b"listen" => {
|
||||||
loop {
|
loop {
|
||||||
let handle = self.handles.get_mut(&id).ok_or(Error::new(EBADF))?;
|
let handle = self.handles.get_mut(&id).ok_or(Error::new(EBADF))?;
|
||||||
let listener = handle.require_listener()?;
|
let listener = handle.require_listener()?;
|
||||||
|
let listener_path = listener.path.clone();
|
||||||
|
|
||||||
break if let Some(remote_id) = listener.awaiting.pop_front() {
|
break if let Some(remote_id) = listener.awaiting.pop_front() {
|
||||||
let new_id = self.next_id;
|
let new_id = self.next_id;
|
||||||
let new = handle.accept(remote_id);
|
let mut new = handle.accept(remote_id);
|
||||||
|
|
||||||
// Hook the remote side, assuming it's still
|
// Hook the remote side, assuming it's still
|
||||||
// connected, up to this one so the connection is
|
// connected, up to this one so the connection is
|
||||||
@@ -179,6 +208,8 @@ impl SchemeBlockMut for ChanScheme {
|
|||||||
}
|
}
|
||||||
post_fevent(&mut self.socket, remote_id, EVENT_WRITE)?;
|
post_fevent(&mut self.socket, remote_id, EVENT_WRITE)?;
|
||||||
|
|
||||||
|
new.path = listener_path;
|
||||||
|
|
||||||
self.handles.insert(new_id, new);
|
self.handles.insert(new_id, new);
|
||||||
self.next_id += 1;
|
self.next_id += 1;
|
||||||
Ok(Some(new_id))
|
Ok(Some(new_id))
|
||||||
@@ -244,6 +275,23 @@ impl SchemeBlockMut for ChanScheme {
|
|||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result<Option<usize>> {
|
||||||
|
// Write scheme name
|
||||||
|
const PREFIX: &[u8] = b"chan:";
|
||||||
|
let len = cmp::min(PREFIX.len(), buf.len());
|
||||||
|
buf[..len].copy_from_slice(&PREFIX[..len]);
|
||||||
|
if len < PREFIX.len() {
|
||||||
|
return Ok(Some(len));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write path
|
||||||
|
let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
|
||||||
|
let path = handle.path.as_ref().ok_or(Error::new(EBADF))?;
|
||||||
|
let len = cmp::min(path.len(), buf.len() - PREFIX.len());
|
||||||
|
buf[PREFIX.len()..][..len].copy_from_slice(&path.as_bytes()[..len]);
|
||||||
|
|
||||||
|
Ok(Some(PREFIX.len() + len))
|
||||||
|
}
|
||||||
fn fsync(&mut self, id: usize) -> Result<Option<usize>> {
|
fn fsync(&mut self, id: usize) -> Result<Option<usize>> {
|
||||||
self.handles.get(&id)
|
self.handles.get(&id)
|
||||||
.ok_or(Error::new(EBADF))
|
.ok_or(Error::new(EBADF))
|
||||||
@@ -268,6 +316,10 @@ impl SchemeBlockMut for ChanScheme {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn close(&mut self, id: usize) -> Result<Option<usize>> {
|
fn close(&mut self, id: usize) -> Result<Option<usize>> {
|
||||||
|
if let Some(_null) = self.nulls.remove(&id) {
|
||||||
|
return Ok(Some(0));
|
||||||
|
}
|
||||||
|
|
||||||
let handle = self.handles.remove(&id).ok_or(Error::new(EBADF))?;
|
let handle = self.handles.remove(&id).ok_or(Error::new(EBADF))?;
|
||||||
|
|
||||||
match handle.extra {
|
match handle.extra {
|
||||||
|
|||||||
Reference in New Issue
Block a user