Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make try_exists return Ok(true) for Windows Unix Sockets #116683

Merged
merged 2 commits into from
Oct 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions library/std/src/fs/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1707,3 +1707,38 @@ fn test_file_times() {
assert_eq!(metadata.created().unwrap(), created);
}
}

#[test]
#[cfg(windows)]
fn windows_unix_socket_exists() {
use crate::sys::{c, net};
use crate::{mem, ptr};

let tmp = tmpdir();
let socket_path = tmp.join("socket");

// std doesn't current support Unix sockets on Windows so manually create one here.
net::init();
unsafe {
let socket = c::WSASocketW(
c::AF_UNIX as i32,
c::SOCK_STREAM,
0,
ptr::null_mut(),
0,
c::WSA_FLAG_OVERLAPPED | c::WSA_FLAG_NO_HANDLE_INHERIT,
);
assert_ne!(socket, c::INVALID_SOCKET);
let mut addr = c::SOCKADDR_UN { sun_family: c::AF_UNIX, sun_path: mem::zeroed() };
let bytes = socket_path.as_os_str().as_encoded_bytes();
addr.sun_path[..bytes.len()].copy_from_slice(bytes);
let len = mem::size_of_val(&addr) as i32;
let result = c::bind(socket, ptr::addr_of!(addr).cast::<c::SOCKADDR>(), len);
c::closesocket(socket);
assert_eq!(result, 0);
}
// Make sure all ways of testing a file exist work for a Unix socket.
assert_eq!(socket_path.exists(), true);
assert_eq!(socket_path.try_exists().unwrap(), true);
assert_eq!(socket_path.metadata().is_ok(), true);
}
2 changes: 2 additions & 0 deletions library/std/src/sys/windows/c/windows_sys.lst
Original file line number Diff line number Diff line change
Expand Up @@ -1964,6 +1964,7 @@ Windows.Win32.Networking.WinSock.ADDRESS_FAMILY
Windows.Win32.Networking.WinSock.ADDRINFOA
Windows.Win32.Networking.WinSock.AF_INET
Windows.Win32.Networking.WinSock.AF_INET6
Windows.Win32.Networking.WinSock.AF_UNIX
Windows.Win32.Networking.WinSock.AF_UNSPEC
Windows.Win32.Networking.WinSock.bind
Windows.Win32.Networking.WinSock.closesocket
Expand Down Expand Up @@ -2058,6 +2059,7 @@ Windows.Win32.Networking.WinSock.SOCK_RDM
Windows.Win32.Networking.WinSock.SOCK_SEQPACKET
Windows.Win32.Networking.WinSock.SOCK_STREAM
Windows.Win32.Networking.WinSock.SOCKADDR
Windows.Win32.Networking.WinSock.SOCKADDR_UN
Windows.Win32.Networking.WinSock.SOCKET
Windows.Win32.Networking.WinSock.SOCKET_ERROR
Windows.Win32.Networking.WinSock.SOL_SOCKET
Expand Down
12 changes: 12 additions & 0 deletions library/std/src/sys/windows/c/windows_sys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -847,6 +847,7 @@ impl ::core::clone::Clone for ADDRINFOA {
}
pub const AF_INET: ADDRESS_FAMILY = 2u16;
pub const AF_INET6: ADDRESS_FAMILY = 23u16;
pub const AF_UNIX: u16 = 1u16;
pub const AF_UNSPEC: ADDRESS_FAMILY = 0u16;
pub const ALL_PROCESSOR_GROUPS: u32 = 65535u32;
#[repr(C)]
Expand Down Expand Up @@ -3813,6 +3814,17 @@ impl ::core::clone::Clone for SOCKADDR {
*self
}
}
#[repr(C)]
pub struct SOCKADDR_UN {
pub sun_family: ADDRESS_FAMILY,
pub sun_path: [u8; 108],
}
impl ::core::marker::Copy for SOCKADDR_UN {}
impl ::core::clone::Clone for SOCKADDR_UN {
fn clone(&self) -> Self {
*self
}
}
pub type SOCKET = usize;
pub const SOCKET_ERROR: i32 = -1i32;
pub const SOCK_DGRAM: WINSOCK_SOCKET_TYPE = 2i32;
Expand Down
7 changes: 7 additions & 0 deletions library/std/src/sys/windows/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1515,6 +1515,13 @@ pub fn try_exists(path: &Path) -> io::Result<bool> {
// as the file existing.
_ if e.raw_os_error() == Some(c::ERROR_SHARING_VIOLATION as i32) => Ok(true),

// `ERROR_CANT_ACCESS_FILE` means that a file exists but that the
// reparse point could not be handled by `CreateFile`.
// This can happen for special files such as:
// * Unix domain sockets which you need to `connect` to
// * App exec links which require using `CreateProcess`
_ if e.raw_os_error() == Some(c::ERROR_CANT_ACCESS_FILE as i32) => Ok(true),

// Other errors such as `ERROR_ACCESS_DENIED` may indicate that the
// file exists. However, these types of errors are usually more
// permanent so we report them here.
Expand Down
Loading