-
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: File.ReadFrom copy_file_range: bad file descriptor on append only file #60181
Comments
I think this is equivalent to:
|
No, I do not think that this is the same.
Even in case this would reproduce the case I'm describing, I wouldn't compare it. In you example the author of the program can control the flags. In my example I can't. I'm just writing to |
(attn @ianlancetaylor; CC @tklauser @panjf2000) |
I think this is because the That check for
I'm not sure why it doesn't fail in that case. I'd still expect |
Change https://go.dev/cl/494915 mentions this issue: |
Change https://go.dev/cl/494916 mentions this issue: |
Wild guessing w/o reading the (Go) sources: Go tries to be smart if both input and output seem to be regular files. (e.g. >>/dev/null doesn't produce the above error, not sure, if we're not on the copy_file_range path then, or of the OS is forgiving here.) So, IMHO Go should get even smarter (as suggested by @tklauser) by checking the mode the output is opened as, or less smarter by just avoiding the copy_file_range when operating file handles it doesn't open on its own (0, 1, 2, and maybe even more, if inheritated from a calling process.) |
…all wrapper This will allow to use the fcntl syscall in packages other than internal/poll. For #60181 Change-Id: I76703766a655f2343c61dad95faf81aad58e007f Reviewed-on: https://go-review.googlesource.com/c/go/+/494916 Reviewed-by: Ian Lance Taylor <iant@google.com> Reviewed-by: Bryan Mills <bcmills@google.com> Auto-Submit: Tobias Klauser <tobias.klauser@gmail.com> Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com> TryBot-Result: Gopher Robot <gobot@golang.org>
This bug broke my simple program that basically just does "io.Copy(os.Stdout, someData())" whenever that program was used to append to a file: "program >> file.txt" ... The err you get is: "write /dev/stdout: copy_file_range: bad file descriptor" |
was any regression test added to prevent regressions of this in the future? A basic e2e test like "go run . </etc/hosts >>/tmp/file-test" should definitely be part of the ci build test suite... |
We believe that this bug is fixed in the upcoming 1.21 release. If you want to send in a test, that would be welcome. It could be in the os package, or in cmd/go/testdata/script. |
Yes I downloaded 1.21rc3 and appending stdout works there. I will see if I find time to contribute. |
Change https://go.dev/cl/517755 mentions this issue: |
Before CL 494915, this test would fail on Linux in io.Copy with error "write /dev/stdout: copy_file_range: bad file descriptor" because the copy_file_range syscall doesn't support destination files opened with O_APPEND, see https://man7.org/linux/man-pages/man2/copy_file_range.2.html#ERRORS For #60181 Change-Id: I2eb4bcac71175121821e0033eb2297a2bc4ec759 Reviewed-on: https://go-review.googlesource.com/c/go/+/517755 Auto-Submit: Tobias Klauser <tobias.klauser@gmail.com> Reviewed-by: Bryan Mills <bcmills@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com> Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
Change https://go.dev/cl/518255 mentions this issue: |
In CL 517755 the test was added in the unconstrained os_test.go because it appeared to be portable, but it turned out not to be valid on plan9. (The build error was masked on the misc-compile TryBots by #61923.) Although the test can also compile and run on Windows, the bug it checks for is specific to Linux and only really needs to run there, so I am moving it to os_unix_test.go instead of adding yet another test file for “Unix and Windows but not Plan 9”. Updates #60181. Change-Id: I41fd11b288217e95652b5daa72460c0d26bde606 Reviewed-on: https://go-review.googlesource.com/c/go/+/518255 Auto-Submit: Bryan Mills <bcmills@google.com> Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com> Run-TryBot: Bryan Mills <bcmills@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
https://go.dev/play/p/c0MHjwdDm4K
Basically
io.Copy(os.Stdout, ...)
And calling the program on the (Linux, Bash) commandline:
What did you expect to see?
No error message.
What did you see instead?
2023/05/14 10:32:34 0 write /dev/stdout: copy_file_range: bad file descriptor
Additional Info
This issues seems to be bound to the type of the input. E.g. running the above examples as
it works as expected (despite the useless use of cat).
For me it seems as if Go tries to be a way too smart. Using
bytes.NewBufferString("...\n")
as input toio.Copy
works too.I'm not sure if this is just my own stupidity, as I didn't find a lot of similar reports.
The text was updated successfully, but these errors were encountered: