-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
std::fs
incorrect behavior when dealing with UNIX domain socket on Windows
#109106
Comments
std::fs
incorect when dealing with UNIX domain socket on Windowsstd::fs
incorrect behavior when dealing with UNIX domain socket on Windows
This is indeed a long standing issue. You also get the same thing with app aliases, etc. The fix I've been considering would be to add a fallback to stat so that if If anyone is interested in trying to implement this then feel very free. I'd be happy to provide guidance if you assign me as the reviewer of your PR. |
@ChrisDenton I can give this a try. @rustbot claim |
fallback to lstat when stat fails on Windows Fixes rust-lang#109106 `@ChrisDenton` please let me know if this is the expected behavior for stat on windows
fallback to lstat when stat fails on Windows Fixes rust-lang#109106 ``@ChrisDenton`` please let me know if this is the expected behavior for stat on windows
fallback to lstat when stat fails on Windows Fixes rust-lang#109106 ```@ChrisDenton``` please let me know if this is the expected behavior for stat on windows
Make `try_exists` return `Ok(true)` for Windows Unix Sockets This is a follow up to rust-lang#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
I tried this code:
I expected to see this happen:
The API should report the given path exists.
Instead, this happened:
When passed a path to a UNIX domain socket on Windows, I get:
Meta
rustc --version --verbose
:Analysis
I think this is simply an unintended consequence of supporting symlinks on Windows. It is interesting that
symlink_metadata
seems to be producing a correct result here (IMO this metadata should be returned bymetadata()
).The differences between
stat
(metadata
) andlstat
(symlink_metadata
) is theReparsePoint
flag.rust/library/std/src/sys/windows/fs.rs
Lines 1152 to 1158 in 8d4adad
On Windows, UNIX domain sockets are implemented as reparse points just like symlink. However Rust is only setting the
FILE_FLAG_OPEN_REPARSE_POINT
flag when we are testing for symlink. Without this flagCreateFileW
is going to return the access error above.I think the issue is that, the standard library didn't consider that the possibility to have other type of files that are reparse points but not symlinks.
I'm not sure what is the best fix for this, but this is kinda surprising.
The text was updated successfully, but these errors were encountered: