-
Notifications
You must be signed in to change notification settings - Fork 17.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
os: opening an existing file with O_CREATE|O_TRUNC and permission 0 changes file to be read-only on Windows #38225
Comments
I think you're right; the file now has the |
It's been a few months since I looked at that code, but last I looked at it, for non writable modes, instead of twiddling ACLs, the Go mapping is to instead set the readonly file attribute. |
Here it is: go/src/syscall/syscall_windows.go Lines 335 to 337 in 801cd7c
It's then reflected in the other direction with |
Right, I understand that it's intention to set readonly under at least some circumstances. That's your https://golang.org/cl/202439. My question is whether it's intentional to apply them when opening an existing file, rather than creating a new one. |
I did not know Alex |
From the From |
I disagree. That is not how I read this documentation. But I won't argue with you. Anyway, I don't see how we can implement what you require. Looking at windows version of We should include FILE_ATTRIBUTE_READONLY, if I don't see how to deal with CREATE_ALWAYS. CREATE_ALWAYS deals with both exiting and non-existing files. We want FILE_ATTRIBUTE_READONLY set for new files, but not for existing files. Here is CreateFile Windows API documentation. https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew Alex |
@ianlancetaylor touched the doc last, so I'm curious if he has an opinion. But anyway, fine; I'll change goimports to stat the file and use its permissions for the WriteFile call. |
I think that for Therefore, for |
Change https://golang.org/cl/229297 mentions this issue: |
I understand what we are trying to achieve. @heschik already explained it to me.
GetFileInformationByHandle requires file handle, so you will need to use CreateFile first, then GetFileInformationByHandle, then CloseHandle, then you will call existing CreateFile. That is 4 calls, instead of 1 for every single opened file. And what about the race between GetFileInformationByHandle and second CreateFile? What happens, if another program or thread changes file attribute? I don't think having FILE_ATTRIBUTE_READONLY mapped to UNIX attribute is worth the trouble. Maybe we should just revert https://golang.org/cl/202439 ? @zx2c4 what do you think?
@heschik Thank you for preparing this CL. But, lets see, if we can find general solution. Alex |
Since this behavior was released in 1.14, we need a fix in goimports regardless of future behavior. I changed the CL to update this bug rather than close it. |
@alexbrainman I don't think it's too bad. We only need to check the existing file attribute in the case of And actually I think it's even simpler. In the problematic case, we should call So I think this just adds one extra system call for an unusual case. |
As of Go 1.14, WriteFile on Windows will set read-only on existing files if you pass 0 for perms. Pass the pre-existing permissions. Updates golang/go#38225. Change-Id: I3174469efd4dc4c7eacc8522386a0712cfa39d11 Reviewed-on: https://go-review.googlesource.com/c/tools/+/229297 Reviewed-by: Ian Cottrell <iancottrell@google.com> Run-TryBot: Heschi Kreinick <heschi@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
@andybons this issue is about broken os package. It should not be labeled as tools. And we should fix the issue before releasing go 1.15, because we broke this code in go 1.14. Thank you. Alex |
@gopherbot Please open a backport to 1.14. This is a regression that was introduced in 1.14. |
Backport issue(s) opened: #39158 (for 1.14). Remember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://golang.org/wiki/MinorReleases. |
Change https://golang.org/cl/234534 mentions this issue: |
The above code automatically sets the test.txt file to read only |
Change https://golang.org/cl/234686 mentions this issue: |
…r O_CREAT|O_TRUNC On Windows, calling syscall.Open(file, O_CREAT|O_TRUNC, 0) for a file that already exists would change the file to be read-only. That is not how the Unix syscall.Open behaves, so avoid it on Windows by calling CreateFile twice if necessary. For #38225 Fixes #39158 Change-Id: I70097fca8863df427cc8a97b9376a9ffc69c6318 Reviewed-on: https://go-review.googlesource.com/c/go/+/234534 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Alex Brainman <alex.brainman@gmail.com> (cherry picked from commit 567556d) Reviewed-on: https://go-review.googlesource.com/c/go/+/234686 Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
As far as I can tell, 1.14.1 is the latest version, so yes.
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
What did you expect to see?
I expected that the file remain writable after
goimports -w
What did you see instead?
goimports -w
leaves the formatted file with the read-only flag set.Bonus information
I suspect the problem is right here
https://github.com/golang/tools/blob/9fc00b0a7ff6189dbfbf7326432f0857c366fd6a/cmd/goimports/goimports.go#L163
and that it was caused by this
https://golang.org/doc/go1.14#windows
The text was updated successfully, but these errors were encountered: