You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
proposal: os: Create/Open/OpenFile() set FILE_SHARE_DELETE on windows #32088
If you develop on Windows and deploy to Linux etc, and your code relies on this undocumented GOOS=windows behavior of os.Rename() & .Remove(), it is broken and perhaps vulnerable. Note that package "os" has fifteen mentions of other Windows-specific behavior.
Therefore syscall.Open() should use file_share_delete by default, and syscall should provide both:
a) a global switch to disable it (for any existing apps that rely on its absence), and
b) a flag for use with os.OpenFile() to disable it on a specific file handle.
Update after #32088 (comment) by @rsc:
a) os.Create/Open/OpenFile() should always enable file_share_delete on Windows,
b) syscall.Open() on Windows should accept a flag which enables file_share_delete, and
c) syscall on Windows should export a constant for the new flag.
The docs for os.Remove() should also note that to reuse a filename after deleting an open file on Windows, one must do: os.Rename(path, unique_path); os.Remove(unique_path).
@alexbrainman when doing reliable file I/O (as for databases), it's standard practice to create a file with a temporary name, write it, fsync it, and rename it.
Open files can be renamed or deleted by default on Unix. It seems like an oversight that the Windows flag for this capability is not set. I doubt we'll convince the Go team to change the way it works for Linux & MacOS :-)
@mattn pls apply the fix I described and try the code I posted.
IIRC, we've made a few adjustments to GOOS=windows & plan9 behavior in the past to more closely match Unix semantics. I wouldn't mind making this be another such case if the semantics are close enough. @mattn's comment, however, suggests the behavior is not close enough so it might not be worth it.
I don't want to see some global option, though. That just seems like a debugging nightmare.
Reacted by Martin Kiesel, Dan Kortschak, inliquid and Ahmed W.
I'm really disappointed by this response.
Copying this large swath of code, which is largely not even understood (as
in why is this doing what it's doing) just so we can add a single option
that the system itself supports, just that Go, mostly likely I assume not
even intentionally, doesn't provide a means to pass the option down even to
syscall.Open seems like a rediculous situation.
Why do I have to rewrite syscall.Open to pass this option in?
On Sat, Oct 5, 2019 at 18:43 Alex Brainman ***@***.***> wrote:
Alex, one can loop the rename attempt if outside access is allowed, ...
If you are prepared to loop the rename, you don't need to change anything
in Go repo code. Your program will work as good as it works now.
Right now, the only solution is to literally copy a bunch of code out of
Go's standard library, change one line, and then maintain that fork forever.
I think copying code into separate package is fine. While investigating
moby/moby#39974 <moby/moby#39974> I got the same
idea. I don't think there is much code there to maintain. In fact I
implemented just that
https://github.com/alexbrainman/goissue34681
Feel free to copy or use as is. Maybe, given, there is so much interest in
this functionality, you actually create proper package that can be shared
and used by others. This way you can keep it up to date and fix bugs.
@rsc <https://github.com/rsc>, before you decline this, let's hear what
Alex thinks of your O_ALLOW_DELETE proposal.
Please, try
https://github.com/alexbrainman/goissue34681
first. If you not satisfied for some reason, we could discuss adding new
functionality to Go repo.
Thank you.
Alex
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#32088?email_source=notifications&email_token=AAGDCZXHULQEMHAPTO6ZUJTQNFGE7A5CNFSM4HNPNYIKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEAN7QIQ#issuecomment-538703906>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAGDCZWYUNMCTAGO567AV73QNFGE7ANCNFSM4HNPNYIA>
.
--
- Brian Goff
Reacted by Zik Aeroh, Dmitriy Matrenichev, Morgan Bauer and Tom Thorogood
@rsc, since Alex is also opposed to an os.OpenFile() flag, should we do nothing?
How about putting this feature behind a build flag?
As to whether "Go worked fine on Windows for nearly 10 years," it definitely did not, in the event you needed to rename an open file. (It was also broken on Windows 8/10 laptops for the past 7 years.)
I have my own fork of os.OpenFile and syscall.Open already in moby/moby.
Why are we being so dismissive here?
On Tue, Oct 8, 2019 at 01:47 Alex Brainman ***@***.***> wrote:
I'm really disappointed by this response.
I am sorry you feel that way. But did you actually tried to use my package?
Alex
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#32088?email_source=notifications&email_token=AAGDCZRV72GY4IJQJVJWMYTQNRCIHA5CNFSM4HNPNYIKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEATNATA#issuecomment-539414604>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAGDCZRNYSMIE6BX77XJVWDQNRCIHANCNFSM4HNPNYIA>
.
I'd suggest this specific proposal be declined. We're not going to introduce a bunch of TOCTOU security bugs for Windows users who relied on the existing behavior of os.OpenFile.
The larger question here is, "how can we expose to Go users the large variety of interesting flags for Windows' CreateFile and NtCreateFile functions?" I expect we'll be able to address those in different proposals, but certainly not by turning them all on by default as this here suggests.
@zx2c4 did you read the whole thread? We weren't able to identify a single case of a Go user who relies on the existing, undocumented behavior, despite repeated attempts.
Activity
bradfitz commentedon May 16, 2019
/cc @alexbrainman
alexbrainman commentedon May 18, 2019
Why should it?
Alex
networkimprov commentedon May 18, 2019
FILE_SHARE_DELETE enables the code example above, which works on MacOS & Linux but fails on Windows. It's also necessary for:
alexbrainman commentedon May 19, 2019
Why don't we adjust MacOS & Linux code instead?
I don't understand what you are trying to say.
Alex
mattn commentedon May 19, 2019
@networkimprov You must call Remove after Close() on Windows.
networkimprov commentedon May 19, 2019
@alexbrainman when doing reliable file I/O (as for databases), it's standard practice to create a file with a temporary name, write it, fsync it, and rename it.
Open files can be renamed or deleted by default on Unix. It seems like an oversight that the Windows flag for this capability is not set. I doubt we'll convince the Go team to change the way it works for Linux & MacOS :-)
@mattn pls apply the fix I described and try the code I posted.
alexbrainman commentedon May 19, 2019
I am fine the way things are now.
Alex
networkimprov commentedon May 19, 2019
Is there a rationale for omitting this common capability in Windows?
Can you provide a switch in syscall_windows.go so that we can select the Unix behavior at program start?
mattn commentedon May 19, 2019
I'm okay that we add new API or flags. But I have objection to change current behavior. Since FILE_SHARE_DELETE is not same as Unix behavior.
Comple this code on Windows, and try to run as
test.exe. While this app is waiting hit-a-key, open new cmd.exe, delete "test.txt" like following.The file can be deleted but remaining there while the process exists. So this change will not work well for your expected.
networkimprov commentedon May 19, 2019
I realize the directory entry isn't removed but the docs say
So I don't understand your screen log.
Anyway, a switch like this would be fine:
ericlagergren commentedon May 19, 2019
I’d like to mention that I’ve been bitten by this at work before.
Basically we had:
The code ran fine on our unix-based CI platforms, but exploded on Windows.
Assuming there aren’t any weird side effects, it would be nice if things just worked.
bradfitz commentedon May 19, 2019
IIRC, we've made a few adjustments to GOOS=windows & plan9 behavior in the past to more closely match Unix semantics. I wouldn't mind making this be another such case if the semantics are close enough. @mattn's comment, however, suggests the behavior is not close enough so it might not be worth it.
I don't want to see some global option, though. That just seems like a debugging nightmare.
199 remaining items
cpuguy83 commentedon Oct 6, 2019
alexbrainman commentedon Oct 8, 2019
I am sorry you feel that way. But did you actually tried to use my package?
Alex
networkimprov commentedon Oct 8, 2019
@rsc, since Alex is also opposed to an os.OpenFile() flag, should we do nothing?
How about putting this feature behind a build flag?
As to whether "Go worked fine on Windows for nearly 10 years," it definitely did not, in the event you needed to rename an open file. (It was also broken on Windows 8/10 laptops for the past 7 years.)
cpuguy83 commentedon Oct 8, 2019
zx2c4 commentedon Oct 9, 2019
I'd suggest this specific proposal be declined. We're not going to introduce a bunch of TOCTOU security bugs for Windows users who relied on the existing behavior of os.OpenFile.
The larger question here is, "how can we expose to Go users the large variety of interesting flags for Windows'
CreateFileandNtCreateFilefunctions?" I expect we'll be able to address those in different proposals, but certainly not by turning them all on by default as this here suggests.networkimprov commentedon Oct 9, 2019
@zx2c4 did you read the whole thread? We weren't able to identify a single case of a Go user who relies on the existing, undocumented behavior, despite repeated attempts.
rsc commentedon Oct 9, 2019
It's been a week since #32088 (comment), and there is still very much no clear consensus, which means we should decline this.
Declined.
networkimprov commentedon Dec 15, 2019
I've posted a summary of options with pros & cons in #34681 (comment).
always open a stream with FILE_SHARE_DELETE according to the POST gol…
always open a stream with FILE_SHARE_DELETE according to the POST gol…