
Closes #19892 This PR builds on top of #20587 and improves upon it. Release Notes: - N/A --------- Co-authored-by: Kirill Bulatov <kirill@zed.dev>
76 lines
2 KiB
Rust
76 lines
2 KiB
Rust
use std::{
|
|
io::{Error, ErrorKind, Result},
|
|
path::Path,
|
|
sync::Once,
|
|
};
|
|
|
|
use windows::Win32::Networking::WinSock::{
|
|
ADDRESS_FAMILY, AF_UNIX, SOCKADDR_UN, SOCKET_ERROR, WSAGetLastError, WSAStartup,
|
|
};
|
|
|
|
pub(crate) fn init() {
|
|
static ONCE: Once = Once::new();
|
|
|
|
ONCE.call_once(|| unsafe {
|
|
let mut wsa_data = std::mem::zeroed();
|
|
let result = WSAStartup(0x202, &mut wsa_data);
|
|
if result != 0 {
|
|
panic!("WSAStartup failed: {}", result);
|
|
}
|
|
});
|
|
}
|
|
|
|
// https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/
|
|
pub(crate) fn sockaddr_un<P: AsRef<Path>>(path: P) -> Result<(SOCKADDR_UN, usize)> {
|
|
let mut addr = SOCKADDR_UN::default();
|
|
addr.sun_family = ADDRESS_FAMILY(AF_UNIX);
|
|
|
|
let bytes = path
|
|
.as_ref()
|
|
.to_str()
|
|
.map(|s| s.as_bytes())
|
|
.ok_or(ErrorKind::InvalidInput)?;
|
|
|
|
if bytes.contains(&0) {
|
|
return Err(Error::new(
|
|
ErrorKind::InvalidInput,
|
|
"paths may not contain interior null bytes",
|
|
));
|
|
}
|
|
if bytes.len() >= addr.sun_path.len() {
|
|
return Err(Error::new(
|
|
ErrorKind::InvalidInput,
|
|
"path must be shorter than SUN_LEN",
|
|
));
|
|
}
|
|
|
|
unsafe {
|
|
std::ptr::copy_nonoverlapping(
|
|
bytes.as_ptr(),
|
|
addr.sun_path.as_mut_ptr().cast(),
|
|
bytes.len(),
|
|
);
|
|
}
|
|
|
|
let mut len = sun_path_offset(&addr) + bytes.len();
|
|
match bytes.first() {
|
|
Some(&0) | None => {}
|
|
Some(_) => len += 1,
|
|
}
|
|
Ok((addr, len))
|
|
}
|
|
|
|
pub(crate) fn map_ret(ret: i32) -> Result<usize> {
|
|
if ret == SOCKET_ERROR {
|
|
Err(Error::from_raw_os_error(unsafe { WSAGetLastError().0 }))
|
|
} else {
|
|
Ok(ret as usize)
|
|
}
|
|
}
|
|
|
|
fn sun_path_offset(addr: &SOCKADDR_UN) -> usize {
|
|
// Work with an actual instance of the type since using a null pointer is UB
|
|
let base = addr as *const _ as usize;
|
|
let path = &addr.sun_path as *const _ as usize;
|
|
path - base
|
|
}
|