about summary refs log tree commit diff
path: root/library/std/src/sys
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-10-15 05:50:30 +0000
committerbors <bors@rust-lang.org>2023-10-15 05:50:30 +0000
commitff5664d600b7d31b43f1109587dabe008bb73af1 (patch)
tree379ec4a90d7b4d4fed2d5d295f23aa32c15d530f /library/std/src/sys
parentdda7d4c9cf1112e98886df056b57e9f6ac3b6822 (diff)
parent2f5dea09784c5c0dc80b31aea08822a1dc4ecd77 (diff)
downloadrust-ff5664d600b7d31b43f1109587dabe008bb73af1.tar.gz
rust-ff5664d600b7d31b43f1109587dabe008bb73af1.zip
Auto merge of #116683 - ChrisDenton:exists, r=Mark-Simulacrum
Make `try_exists` return `Ok(true)` for Windows Unix Sockets

This is a follow up to #109106 but for[ `fs::try_exists`](https://doc.rust-lang.org/std/fs/fn.try_exists.html), which doesn't need to get the metadata of a file (which can fail even if a file exists).

`fs::try_exists` currently fails on Windows if encountering a Unix Domain Socket (UDS). This PR fixes it by checking for an error code that's returned when there's a failure to use a reparse point.

## Reparse points

A reparse point is a way to invoke a filesystem filter on a file instead of the file being opened normally. This is used to implement symbolic links (by redirecting to a different path) but also to implement other types of special files such as Unix domain sockets. If the reparse point is not a link type then opening it with `CreateFileW` may fail with `ERROR_CANT_ACCESS_FILE` because the filesystem filter does not implement that operation. This differs from resolving links which may fail with errors such as `ERROR_FILE_NOT_FOUND` or `ERROR_CANT_RESOLVE_FILENAME`.

So `ERROR_CANT_ACCESS_FILE` means that the file exists but that we can't open it normally. Still, the file does exist on the filesystem so `try_exists` should report that as `Ok(true)`.

r? libs
Diffstat (limited to 'library/std/src/sys')
-rw-r--r--library/std/src/sys/windows/c/windows_sys.lst2
-rw-r--r--library/std/src/sys/windows/c/windows_sys.rs12
-rw-r--r--library/std/src/sys/windows/fs.rs7
3 files changed, 21 insertions, 0 deletions
diff --git a/library/std/src/sys/windows/c/windows_sys.lst b/library/std/src/sys/windows/c/windows_sys.lst
index 0aca37e2d45..dad4a4223b2 100644
--- a/library/std/src/sys/windows/c/windows_sys.lst
+++ b/library/std/src/sys/windows/c/windows_sys.lst
@@ -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
@@ -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
diff --git a/library/std/src/sys/windows/c/windows_sys.rs b/library/std/src/sys/windows/c/windows_sys.rs
index 851d15915c7..20b44966a39 100644
--- a/library/std/src/sys/windows/c/windows_sys.rs
+++ b/library/std/src/sys/windows/c/windows_sys.rs
@@ -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)]
@@ -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;
diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs
index 0113196b824..6ded683aade 100644
--- a/library/std/src/sys/windows/fs.rs
+++ b/library/std/src/sys/windows/fs.rs
@@ -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.