From: Tobias Klauser Date: Wed, 9 Aug 2023 14:51:10 +0000 (+0200) Subject: os: test that copying to append-only files doesn't fail on Linux X-Git-Tag: go1.22rc1~1350 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=e6637f32930c934ad3836805288aa473717ee083;p=gostls13.git os: test that copying to append-only files doesn't fail on Linux 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 Reviewed-by: Bryan Mills TryBot-Result: Gopher Robot Reviewed-by: Michael Knyszek Run-TryBot: Tobias Klauser --- diff --git a/src/os/os_test.go b/src/os/os_test.go index 94c3ad04f3..28256ee213 100644 --- a/src/os/os_test.go +++ b/src/os/os_test.go @@ -3270,3 +3270,59 @@ func TestPipeCloseRace(t *testing.T) { t.Errorf("got nils %d errs %d, want 2 2", nils, errs) } } + +// Test that copying to files opened with O_APPEND works and +// the copy_file_range syscall isn't used on Linux. +// +// Regression test for go.dev/issue/60181 +func TestIssue60181(t *testing.T) { + defer chtmpdir(t)() + + want := "hello gopher" + + a, err := CreateTemp("", "a") + if err != nil { + t.Fatal(err) + } + a.WriteString(want[:5]) + a.Close() + + b, err := CreateTemp("", "b") + if err != nil { + t.Fatal(err) + } + b.WriteString(want[5:]) + b.Close() + + afd, err := syscall.Open(a.Name(), syscall.O_RDWR|syscall.O_APPEND, 0) + if err != nil { + t.Fatal(err) + } + + bfd, err := syscall.Open(b.Name(), syscall.O_RDONLY, 0) + if err != nil { + t.Fatal(err) + } + + aa := NewFile(uintptr(afd), a.Name()) + defer aa.Close() + bb := NewFile(uintptr(bfd), b.Name()) + defer bb.Close() + + // This would fail on Linux in case the copy_file_range syscall was used because it doesn't + // support destination files opened with O_APPEND, see + // https://man7.org/linux/man-pages/man2/copy_file_range.2.html#ERRORS + _, err = io.Copy(aa, bb) + if err != nil { + t.Fatal(err) + } + + buf, err := ReadFile(aa.Name()) + if err != nil { + t.Fatal(err) + } + + if got := string(buf); got != want { + t.Errorf("files not concatenated: got %q, want %q", got, want) + } +}