-
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: inconsistent cross-platform behavior: os.OpenFile/os.Write* #21322
Comments
Or use os.Create which deals with these cross platform issues.
…On Sun, 6 Aug 2017, 11:54 Prasanna V. Loganathar ***@***.***> wrote:
What version of Go are you using (go version)?
go version go1.8.3 windows/amd64
go version go1.8.3 linux/amd64
What operating system and processor architecture are you using (go env)?
Skipping as the details are covered below.
What did you do?
In Windows, the following program will happily end up writing to the file
with no issues.
package main
import "os"
import "fmt"
func main() {
flag := os.O_CREATE
file, err := os.OpenFile("test.log", flag, os.FileMode(0644))
if err != nil {
fmt.Println(err)
}
defer file.Close()
n, err := file.WriteString("Hello")
if err != nil {
fmt.Println(err)
}
fmt.Printf("Written: %v\r\n", n)
fmt.Println("Good-bye.")
}
However, in linux this will fail to write with a bad file descriptor
error, since there's no write permission that's given. The
os.O_RDWR/WRONLY is required during OpenFile for the write to succeed.
Possible solutions
1. Document it.
2. Do run time checks to ensure consistent behavior.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#21322>, or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAAcA2qI6hP5wI5er7hO7kgis-Rl6a9Tks5sVRzIgaJpZM4OunKf>
.
|
@davecheney, you can't, if you need to create the file it doesn't exist, or just append, which is quite common.. logging for instance. |
Note: This is because, on Windows, the syscall package actually goes one step further here: https://github.com/golang/go/blob/master/src/syscall/syscall_windows.go#L269 To ensure that when APPEND flag is given, it also add the write perm. Should this behavior be added in Linux also? It make perfect sense semantically. |
To save looking through the link, the issue is that on Windows We could change Windows, which could potentially break existing working programs on Windows. We could change other systems in the syscall package. This would be annoying to code but would be unlikely to break anybody. It would remove a small and probably unimportant layer of protection from programs that use We could make the similar change in the os package, which would be less annoying but have the same minor drawbacks. We could simply document it. We could ignore it. |
I think a better way to handle this would be to take a page from how I think this is far superior design. I find myself have to specify a sensible default for |
@ianlancetaylor I don't see anything sinister in any of your proposals. I like your last suggestion (to ignore this issue) the best. Go on Windows does many things differently then on other OSes. And this is just one of them. I don't see why it is important for the program above to behave the same on different OSes. Last os.FileMode(0644) parameter is meaningless on Windows - why we should care about it? Alex |
That's rather a saddening comment from a team member of a language which happens to have cross-platform as one of it's core values.
Since it does nothing in windows, you can effectively ignore fileMode - and it's fairly common to develop on windows, and deploy on linux. (I have been doing this for as long as I can remember and now thanks to WSL - I barely ever use linux on desktops - and I suspect there would be a good number of us) Now, you write Also, above point, again. |
I prefer to simply document it. package os's purpose is not to hide every detail, just to provide a consistent interface. https://groups.google.com/forum/#!msg/golang-dev/TlLZoZjJuCk/oQKXUkzGhoEJ |
@mattn, I agree with the comment on the link and simply documenting it as an immediate resolution to the issue as well - I can take this up, and submit a CL in a few days when I get time. That being said, I also wonder if chalking it as we cannot deal with every detail, is the best strategy here especially when a std lib apis like Rust's has clearly demonstrated a better (and simpler) design that covers both sides of the design. A builder pattern like that, will also end up removing a bunch of complicated flags case handling in windows and make the overall code nicer and more importantly I wonder if Besides, I wouldn't have a problem with this, if file handing was simply delegated to the OS on all the OS - which implies consistent and predictable behavior. But here, Go's std library doesn't do that as well. It tries to - neither here nor there - which makes things unpredictable and hard to determine. |
Cross-platform is important, but there are other things that Go developers care about too.
It would be nice if we could just deploy code on another OS and it will work. But I doubt it is possible without real testing on real OS.
I am not sure I like any new documentation here. What are you going to say? I don't see that documentation affecting many people, but everyone will have to read and comprehend new text.
You are talking about things that cannot be changed now. Maybe for Go2? Make suggestion for Go2, if you have some great ideas. Alex |
I do think that OpenFile and these flags are a bit too low-level, which is why we introduced os.Open and os.Create. It's possible we need another so that OpenFile is essentially never needed; that is, needed only when you really need low-level system flags. But that's not where we are today. The current docs for the constants say:
Let's add: "Each call to OpenFile should specify exactly one of O_RDONLY, O_WRONLY, or O_RDWR." |
Change https://golang.org/cl/74550 mentions this issue: |
Change https://golang.org/cl/75250 mentions this issue: |
Updates #21322 Change-Id: Ib03ee9dbe1b44c2fecd51f2f2c23a88482158e7e Reviewed-on: https://go-review.googlesource.com/75250 Reviewed-by: Rob Pike <r@golang.org>
What version of Go are you using (
go version
)?go version go1.8.3 windows/amd64
go version go1.8.3 linux/amd64
What operating system and processor architecture are you using (
go env
)?Skipping as the details are covered below.
What did you do?
In Windows, the following program will happily end up writing to the file with no issues.
However, in linux this will fail to write with a bad file descriptor error, since there's no write permission that's given. The
os.O_RDWR/WRONLY
is required duringOpenFile
for the write to succeed.Possible solutions
The text was updated successfully, but these errors were encountered: