-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
File.Unix: Replace: increase Windows compatibility #50234
Conversation
- When source and destination are not a file throw UnauthorizedAccessException. - When source and destination are the same file throw IOException.
This would need a breaking change note if we take it... |
Unfortunately, we don't have great ability to look at API usage by OS (we actively discourage those publishing patterns, particularly for managed libraries). All up, File.Replace is a widely-used API. Given its popularity and its age (around since NetFx 2.0), it is a safe bet that most of the code using this expects the semantics provided by Windows implementations. Since consistency is an important principle in .NET, consolidating on that behavior makes sense. It looks like this change affects more than exceptional scenarios (that is, things that didn't throw on Linux will now throw). If so, are there patterns that could be employed that would allow code to get the same replace semantics as the previous Linux behavior? I also worry about the non-atomicity of the implemented checks. If these exceptional conditions are reliably atomic on Windows (the result of the underlying Win32 call), we've taken predictable (although inconsistent between OS) behavior and turned it into a potential reliability issue on Linux. I'm not a Linux filesystem expert. What would it take to provide atomicity here? |
The atomicity only relates to whether you get the right exception. It doesn't affect whether the operation succeeds or fails. We already have precedent for this: runtime/src/libraries/System.IO.FileSystem/src/System/IO/FileSystemInfo.Unix.cs Lines 69 to 75 in 1ee59da
Unfortunately it's not avoidable I think if we want to throw the same exceptions. |
FYI, the inconsistencies I've found in There are also inconsistencies in There are also lots of other issues documented throughout that code file. The biggest one is the nonsense |
There's no way to check this atomically. The non-atomic checks will expose the cross-platform difference that are now only revealed when running on the other platform. |
@mikernet if there are some things you'd like, can you create issues for them? That will improve visibility, and there can be some discussion on what makes sense. |
@danmoseley @marklio is this PR good to merge? |
Paging this back in. The only behavior that used to work but now does not, is I think the code change is fine. |
Yes, and copying from a file to the same file will now also throw. |
The answer here is yes, on Unix you will need to replace |
Agreed. It seems like one of our principles has been that carrying cross-plat behavioral differences into the future is untenable. I think we just need to be sure that the "correct" patterns are discoverable for folks moving forward that hit the exceptions. Usually, our tools there are breaking change docs. An article on the right way to author cross-plat file operations would probably be super useful. |
@adamsitnik @carlossanlop @jozkee the IO crew can one of you please make a call and merge if you're comfortable. |
@jkotas any objection to
|
Fine with me.
We are trying to do a best effort Windows emulation on Unix here. I am pretty sure that there are still number of subtle differences, in particular around what is done atomically and what are possible error patterns. Also, Windows emulation on Unix is not free. Notice that this change adds two extra file system syscalls to this APIs. To write robust performant cross-platform code, one may want to avoid this type of APIs. |
@carlossanlop / @jozkee / @adamsitnik -- Please target getting this reviewed so we can make a final decision before Preview 6 snaps. |
Conflicts: src/libraries/System.IO.FileSystem/src/Resources/Strings.resx New strings were moved to: src/libraries/System.Private.CoreLib/src/Resources/Strings.resx
I resolved the conflicts. The |
Unfortunately no dump - our scripts may be faulty. Asking.. |
I've restarted the checks and will check back in on them... |
Thanks @tmds! |
Breaking change doc: dotnet/docs#26323 |
Fixes #49796
@danmoseley @stephentoub ptal
cc @mikernet