-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Fix different behaviour of OpenOptions between Windows en Linux #26772
Conversation
case #1: A file is opened as read-only and with `.truncate(true)`. On Windows this fails with `Error { repr: Os { code: 87, message: "The parameter is incorrect.\r\n" } }`. On Unix the behaviour is undefined. Solution: also fail on Linux with `Error { repr: Os { code: 22, message: "Invalid argument" } }` This is a breaking change, but only for code that relies on the current undefined behaviour. case #2: A file is opened with `.append(true)`, but without `.write(true)`. On Windows it is possible to append to the file, on linux it fails. Solution: let `.append(true)` imply `.write(true)` on linux. case #3: A file is opened without access options. On Windows it fails at the first read or write. On Linux this falls back to read-only mode. Solution: I prefer to also fail on Linux, with "Invalid argument". But this is a breaking change... It is also possible to add the same fallback on Windows.
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @aturon (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. The way Github handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
It would be a nice if someone made a table of every possible flag combination and their current behavior on each platform to highlight the differences. |
I'm pretty ok with this because these corner cases have always been somewhat nebulous in their meaning and what happens. We'll also always want a way to be able to unconditionally pass arguments down (e.g. platform-specific extensions), so whatever you can do today you should be able to do eventually when opting in to the flags. I agree it'd be nice to have a meaning for all combinations on all platforms, but I also think it's fine to not block this PR on that. Can you be sure to add a specific test case for all the cases mentioned here? |
@retep998 This is my best effort for a table containing all possible flag combinations: current behavior
new behavior
current when using .truncate(true)
new when using .truncate(true)
current when using .create(true)
I am not completely sure about However, I can't see much use in creating a file, if you don't have the right to write anything to it proposed when using .create(true)
|
@alexcrichton I have added tests that hopefully cover all cases. Also, |
Thanks @pitdicker! This should come up in triage this week. |
OK, we talked about this in triage the other day, and we didn't reach a concrete conclusion just yet but our thoughts were:
Overall this probably also just needs an extra careful audit to make sure that basically every case is handled (and thanks for the table @pitdicker it's a great start). The libs team thinks this is ok to merge but may want some more thorough review before doing so. |
Could we perhaps add a table like that to the Rust documentation for |
This pull request touches things that can have a bit difficult interactions, and where it is hard to see if all corner cases are covered. To help I am now trying to document everything involved.
So please hold of reviewing some more. |
Ok, I have finally finished documenting... |
I think it is best if I close this pull request for now (I made a bit off a mess of my branch). Also writing the rfc turned up some more things. I will make a new branch and implement the rfc, before a new pull request |
case #1:
A file is opened as read-only and with
.truncate(true)
.On Windows this fails with
Error { repr: Os { code: 87, message: "The parameter is incorrect.\r\n" } }
.On Unix the behaviour is undefined.
Solution: also fail on Linux with
Error { repr: Os { code: 22, message: "Invalid argument" } }
This is a breaking change, but only for code that relies on the current undefined behaviour.
case #2:
A file is opened with
.append(true)
, but without.write(true)
.On Windows it is possible to append to the file, on linux it fails.
Solution: let
.append(true)
imply.write(true)
on linux.case #3:
A file is opened without access options.
On Windows it fails at the first read or write.
On Linux this falls back to read-only mode.
Solution: I prefer to also fail on Linux, with "Invalid argument". But this is a breaking change...
It is also possible to add the same fallback on Windows.
I think that calling setting
.create(true)
with read-only access is also undefined behaviour.Should we check for this also? OpenBSD might be a good candidate to test this.