chan: Keep path in for new Handle.
While supporting AF_UNIX, once an accept() is called in relibc, in turn, a dup() is also called with "listen". While processing this ipcd effectively creates a new handler, losing track of the path of the previous handler. However, it is important to keep this path in the newly created Handler as well, so the socket can be queried later by relibc (when calling fpath()) and fill in appropriately its sockaddr_un struct.
This commit is contained in:
+23
-2
@@ -48,7 +48,8 @@ pub struct NullFile {
|
||||
pub struct Handle {
|
||||
id: usize,
|
||||
flags: usize,
|
||||
extra: Extra
|
||||
extra: Extra,
|
||||
path: Option<String>,
|
||||
}
|
||||
impl Handle {
|
||||
/// Duplicate this listener handle into one that is linked to the
|
||||
@@ -186,10 +187,11 @@ impl SchemeBlockMut for ChanScheme {
|
||||
loop {
|
||||
let handle = self.handles.get_mut(&id).ok_or(Error::new(EBADF))?;
|
||||
let listener = handle.require_listener()?;
|
||||
let listener_path = listener.path.clone();
|
||||
|
||||
break if let Some(remote_id) = listener.awaiting.pop_front() {
|
||||
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
|
||||
// connected, up to this one so the connection is
|
||||
@@ -206,6 +208,8 @@ impl SchemeBlockMut for ChanScheme {
|
||||
}
|
||||
post_fevent(&mut self.socket, remote_id, EVENT_WRITE)?;
|
||||
|
||||
new.path = listener_path;
|
||||
|
||||
self.handles.insert(new_id, new);
|
||||
self.next_id += 1;
|
||||
Ok(Some(new_id))
|
||||
@@ -271,6 +275,23 @@ impl SchemeBlockMut for ChanScheme {
|
||||
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>> {
|
||||
self.handles.get(&id)
|
||||
.ok_or(Error::new(EBADF))
|
||||
|
||||
Reference in New Issue
Block a user