diff --git a/redox-rt/src/protocol.rs b/redox-rt/src/protocol.rs index 4e6ced18d1..4a9faf3c7d 100644 --- a/redox-rt/src/protocol.rs +++ b/redox-rt/src/protocol.rs @@ -62,6 +62,7 @@ pub enum SocketCall { RecvMsg = 5, Unbind = 6, GetToken = 7, + GetPeerName = 8, } #[derive(Clone, Copy, Debug, Eq, PartialEq)] @@ -115,6 +116,7 @@ impl SocketCall { 5 => Self::RecvMsg, 6 => Self::Unbind, 7 => Self::GetToken, + 8 => Self::GetPeerName, _ => return None, }) } diff --git a/src/platform/redox/socket.rs b/src/platform/redox/socket.rs index efc3f7814d..195a92283f 100644 --- a/src/platform/redox/socket.rs +++ b/src/platform/redox/socket.rs @@ -658,7 +658,37 @@ impl PalSocket for Sys { address: *mut sockaddr, address_len: *mut socklen_t, ) -> Result<()> { - inner_get_name(false, socket, address, address_len) + // This is needed until the netstack supports GetPeerName. + let (family, _) = socket_domain_type(socket)?; + + match family { + AF_INET => inner_get_name(false, socket, address, address_len), + AF_UNIX => { + let mut buf = [0; 256]; + let len = redox_rt::sys::sys_call( + socket as usize, + &mut buf, + CallFlags::empty(), + &[SocketCall::GetPeerName as u64], + )?; + if buf.starts_with(b"/scheme/uds_stream/") { + inner_af_unix(&buf[19..len], address, address_len); + } else if buf.starts_with(b"/scheme/uds_dgram/") { + inner_af_unix(&buf[18..len], address, address_len); + } else { + // Socket doesn't belong to any scheme + trace!( + "socket {:?} doesn't match either tcp, udp or chan schemes", + str::from_utf8(buf) + ); + return Err(Errno(ENOTSOCK)); + } + Ok(()) + } + _ => { + return Err(Errno(EAFNOSUPPORT)); + } + } } unsafe fn getsockname(