summaryrefslogtreecommitdiffstats
path: root/library/std/src/os/unix/net/addr.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--library/std/src/os/unix/net/addr.rs93
1 files changed, 25 insertions, 68 deletions
diff --git a/library/std/src/os/unix/net/addr.rs b/library/std/src/os/unix/net/addr.rs
index 094085e19..81ac829d2 100644
--- a/library/std/src/os/unix/net/addr.rs
+++ b/library/std/src/os/unix/net/addr.rs
@@ -1,6 +1,9 @@
use crate::ffi::OsStr;
+#[cfg(any(doc, target_os = "android", target_os = "linux"))]
+use crate::os::net::linux_ext;
use crate::os::unix::ffi::OsStrExt;
use crate::path::Path;
+use crate::sealed::Sealed;
use crate::sys::cvt;
use crate::{fmt, io, mem, ptr};
@@ -224,31 +227,6 @@ impl SocketAddr {
if let AddressKind::Pathname(path) = self.address() { Some(path) } else { None }
}
- /// Returns the contents of this address if it is an abstract namespace
- /// without the leading null byte.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// #![feature(unix_socket_abstract)]
- /// use std::os::unix::net::{UnixListener, SocketAddr};
- ///
- /// fn main() -> std::io::Result<()> {
- /// let namespace = b"hidden";
- /// let namespace_addr = SocketAddr::from_abstract_namespace(&namespace[..])?;
- /// let socket = UnixListener::bind_addr(&namespace_addr)?;
- /// let local_addr = socket.local_addr().expect("Couldn't get local address");
- /// assert_eq!(local_addr.as_abstract_namespace(), Some(&namespace[..]));
- /// Ok(())
- /// }
- /// ```
- #[doc(cfg(any(target_os = "android", target_os = "linux")))]
- #[cfg(any(doc, target_os = "android", target_os = "linux",))]
- #[unstable(feature = "unix_socket_abstract", issue = "85410")]
- pub fn as_abstract_namespace(&self) -> Option<&[u8]> {
- if let AddressKind::Abstract(name) = self.address() { Some(name) } else { None }
- }
-
fn address(&self) -> AddressKind<'_> {
let len = self.len as usize - sun_path_offset(&self.addr);
let path = unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) };
@@ -265,62 +243,41 @@ impl SocketAddr {
AddressKind::Pathname(OsStr::from_bytes(&path[..len - 1]).as_ref())
}
}
+}
- /// Creates an abstract domain socket address from a namespace
- ///
- /// An abstract address does not create a file unlike traditional path-based
- /// Unix sockets. The advantage of this is that the address will disappear when
- /// the socket bound to it is closed, so no filesystem clean up is required.
- ///
- /// The leading null byte for the abstract namespace is automatically added.
- ///
- /// This is a Linux-specific extension. See more at [`unix(7)`].
- ///
- /// [`unix(7)`]: https://man7.org/linux/man-pages/man7/unix.7.html
- ///
- /// # Errors
- ///
- /// This will return an error if the given namespace is too long
- ///
- /// # Examples
- ///
- /// ```no_run
- /// #![feature(unix_socket_abstract)]
- /// use std::os::unix::net::{UnixListener, SocketAddr};
- ///
- /// fn main() -> std::io::Result<()> {
- /// let addr = SocketAddr::from_abstract_namespace(b"hidden")?;
- /// let listener = match UnixListener::bind_addr(&addr) {
- /// Ok(sock) => sock,
- /// Err(err) => {
- /// println!("Couldn't bind: {err:?}");
- /// return Err(err);
- /// }
- /// };
- /// Ok(())
- /// }
- /// ```
- #[doc(cfg(any(target_os = "android", target_os = "linux")))]
- #[cfg(any(doc, target_os = "android", target_os = "linux",))]
- #[unstable(feature = "unix_socket_abstract", issue = "85410")]
- pub fn from_abstract_namespace(namespace: &[u8]) -> io::Result<SocketAddr> {
+#[unstable(feature = "unix_socket_abstract", issue = "85410")]
+impl Sealed for SocketAddr {}
+
+#[doc(cfg(any(target_os = "android", target_os = "linux")))]
+#[cfg(any(doc, target_os = "android", target_os = "linux"))]
+#[unstable(feature = "unix_socket_abstract", issue = "85410")]
+impl linux_ext::addr::SocketAddrExt for SocketAddr {
+ fn as_abstract_name(&self) -> Option<&[u8]> {
+ if let AddressKind::Abstract(name) = self.address() { Some(name) } else { None }
+ }
+
+ fn from_abstract_name<N>(name: &N) -> crate::io::Result<Self>
+ where
+ N: AsRef<[u8]>,
+ {
+ let name = name.as_ref();
unsafe {
let mut addr: libc::sockaddr_un = mem::zeroed();
addr.sun_family = libc::AF_UNIX as libc::sa_family_t;
- if namespace.len() + 1 > addr.sun_path.len() {
+ if name.len() + 1 > addr.sun_path.len() {
return Err(io::const_io_error!(
io::ErrorKind::InvalidInput,
- "namespace must be shorter than SUN_LEN",
+ "abstract socket name must be shorter than SUN_LEN",
));
}
crate::ptr::copy_nonoverlapping(
- namespace.as_ptr(),
+ name.as_ptr(),
addr.sun_path.as_mut_ptr().add(1) as *mut u8,
- namespace.len(),
+ name.len(),
);
- let len = (sun_path_offset(&addr) + 1 + namespace.len()) as libc::socklen_t;
+ let len = (sun_path_offset(&addr) + 1 + name.len()) as libc::socklen_t;
SocketAddr::from_parts(addr, len)
}
}