chan: Support opening "empty" ChanScheme.
Similarly to how the "tcp:" in Redox's netstack supports opening a first empty scheme, only to later on being dup()'ed and set with an appropriate path, this follows the same approach - a map of NullFile structs is kept and initially associated with an id. Next time dup() is called, the true Handle is created, keeping the same definitions of the previously created NullFile. Not that it is important to add support for this in the ipcd to support AF_UNIX sockets, otherwise the socket() created in relibc won't be associated with a address / path.
This commit is contained in:
+31
@@ -40,6 +40,10 @@ impl Default for Connection {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NullFile {
|
||||
pub flags: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Handle {
|
||||
id: usize,
|
||||
@@ -92,6 +96,7 @@ impl Handle {
|
||||
}
|
||||
|
||||
pub struct ChanScheme {
|
||||
nulls: HashMap<usize, NullFile>,
|
||||
handles: HashMap<usize, Handle>,
|
||||
listeners: HashMap<String, usize>,
|
||||
next_id: usize,
|
||||
@@ -100,6 +105,7 @@ pub struct ChanScheme {
|
||||
impl ChanScheme {
|
||||
pub fn new() -> io::Result<Self> {
|
||||
Ok(Self {
|
||||
nulls: HashMap::new(),
|
||||
handles: HashMap::new(),
|
||||
listeners: HashMap::new(),
|
||||
next_id: 0,
|
||||
@@ -124,6 +130,20 @@ impl SchemeBlockMut for ChanScheme {
|
||||
let path = ::std::str::from_utf8(path).or(Err(Error::new(EPERM)))?;
|
||||
|
||||
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();
|
||||
new.flags = flags;
|
||||
|
||||
@@ -154,6 +174,13 @@ impl SchemeBlockMut for ChanScheme {
|
||||
Ok(Some(new_id))
|
||||
}
|
||||
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 {
|
||||
b"listen" => {
|
||||
loop {
|
||||
@@ -268,6 +295,10 @@ impl SchemeBlockMut for ChanScheme {
|
||||
}
|
||||
}
|
||||
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))?;
|
||||
|
||||
match handle.extra {
|
||||
|
||||
Reference in New Issue
Block a user