diff --git a/src/chan.rs b/src/chan.rs index 38df91fca7..97d1f64987 100644 --- a/src/chan.rs +++ b/src/chan.rs @@ -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, handles: HashMap, listeners: HashMap, next_id: usize, @@ -100,6 +105,7 @@ pub struct ChanScheme { impl ChanScheme { pub fn new() -> io::Result { 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> { + 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> { + 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 {