This should be pretty easy to add for anyone that's interested!
Not that easy... I'd probably want to change UnixStream::connect
to take a A: Into<SocketAddr>
and then impl<T: AsRef<Path>> From<T> for SocketAddr
. But, that conversion is fallible (see std::sys::unix::ext::sockaddr_un
). So you need TryInto
. But then you can't supply a SocketAddr
directly until we get impl<T, U> TryFrom<U> for T where T: From<U>
, which requires !
...
Abstract namespaces are Linux only so we'd only want to make them available through a Linux-only method. Probably something like
pub trait UnixStreamExt {
fn connect_abstract(name: &[u8]) -> io::Result<UnixStream>;
}
pub trait SocketAddrExt {
fn as_abstract(&self) -> Option<&[u8]>;
}
That seems like a strange API, to have two different connect functions. You can have it be Linux only to have an extension trait to create a SockAddr on Linux only.
But then you can't supply a SocketAddr directly until we get impl
TryFrom for T where T: From, which requires !...
Why is it impossible to implement TryFrom
from a type to itself without !
?
@sfackler Because we want to indicate that the TryFrom
implementation will never fail, so gotta wait until !
is available.
Actually that might still not work, because now you need TryFrom<Err=io::Error>
for AsRef<Path>
and TryFrom<Err=!>
for SocketAddr
...
@retep998
!
is not the only way to indicate that. String
's FromStr
impl has always been infallible: https://doc.rust-lang.org/src/collections/string.rs.html#1829-1852some_socket_addr.to_socket_addrs()
returned a Result<T, !>
instead of Result<T, io::Error>
"? If you're working in a concrete context you're not going to use try_from
to go from a type to itself, and if you're in an generic context, you're only going use try_from
if you want to deal with the failure case anyway.I'd advice against using that misfeature. In the past 20 years, I've never seen any practical usecase
for that, and it creates more trouble than it's actually worth it.
@metux practical use-case is interoperability with other software that creates an abstract socket?
Ok. Does anyone here run an application which needs that ? I don't recall any in the last two decades.
Would I have opened this ticket if I didn't?
Would I have opened this ticket if I didn't?
No idea, you didn't tell ;-)
I would love to see a PR implementing Linux-only support for abstract addresses. I believe we will be able to reach agreement in the PR without needing to draft an RFC.
Now that TryFrom
and never_type
are close to being stabilized, I took another look at this. https://github.com/rust-lang/rust/commit/d47e9796d97df0c75d25efa25b179918208f1ba9
There's a conflicting implementations issue, a P: AsRef<Path>
might already implement Into<SocketAddr>
:
error[E0119]: conflicting implementations of trait `core::convert::TryFrom<_>` for type `sys::unix::ext::net::SocketAddr`:
--> src/libstd/sys/unix/ext/net.rs:91:1
|
91 | impl<P: AsRef<Path>> TryFrom<P> for SocketAddr {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: conflicting implementation in crate `core`:
- impl<T, U> core::convert::TryFrom<U> for T
where U: core::convert::Into<T>;
Here is the commit that adds SocketAddrExt
https://github.com/rust-lang/rust/commit/c4db0685b181f12c4285dac3d932f1859bba74f5. That should plug right into whatever solution we come up with for the UnixStream API.
I'm interested in this support.
Rather than changing the type of connect
(which seems likely to produce inference errors), why not introduce a couple of new methods, bind_addr
and connect_addr
, which accept a concrete SocketAddr
? Those methods could exist on all platforms; only the mechanism to create an abstract SocketAddr
needs to be a platform-specific extension.
This would avoid dealing with TryFrom
at all, and would avoid introducing potential inference and compatibility issues as well.
I'd like to chime in on this one. There's one neat use case of the abstract namespace and it's implementing robust lock against running in parallel. You try to bind the address and if it's already in use, some other instance is running. Furthermore, unlike the filesystem based ones, these clean up automatically and you don't have to worry about races around unlinking the old (dead) socket „file“.
Sockets with abstract addresses are also often needed to interact with dbus on Linux.
See https://github.com/diwic/dbus-rs/blob/627b42597f13c8f5db3b4259271a5881439c310b/dbus-native/src/sys.rs#L8