mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
internal/poll: in SendFile treat ENOTSUP like EOPNOTSUPP
Fixes #70763 Change-Id: Ifb79b5b0529f7977df0fe1b59d224b8b31df2c9b Reviewed-on: https://go-review.googlesource.com/c/go/+/635396 Reviewed-by: Ian Lance Taylor <iant@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Damien Neil <dneil@google.com> Auto-Submit: Ian Lance Taylor <iant@google.com>
This commit is contained in:
parent
fafd4477f3
commit
077d51909d
2 changed files with 95 additions and 1 deletions
|
|
@ -110,12 +110,20 @@ func sendFile(dstFD *FD, src int, offset *int64, size int64) (written int64, err
|
||||||
// Retry.
|
// Retry.
|
||||||
case syscall.ENOSYS, syscall.EOPNOTSUPP, syscall.EINVAL:
|
case syscall.ENOSYS, syscall.EOPNOTSUPP, syscall.EINVAL:
|
||||||
// ENOSYS indicates no kernel support for sendfile.
|
// ENOSYS indicates no kernel support for sendfile.
|
||||||
// EINVAL indicates a FD type which does not support sendfile.
|
// EINVAL indicates a FD type that does not support sendfile.
|
||||||
//
|
//
|
||||||
// On Linux, copy_file_range can return EOPNOTSUPP when copying
|
// On Linux, copy_file_range can return EOPNOTSUPP when copying
|
||||||
// to a NFS file (issue #40731); check for it here just in case.
|
// to a NFS file (issue #40731); check for it here just in case.
|
||||||
return written, err, written > 0
|
return written, err, written > 0
|
||||||
default:
|
default:
|
||||||
|
// We want to handle ENOTSUP like EOPNOTSUPP.
|
||||||
|
// It's a pain to put it as a switch case
|
||||||
|
// because on Linux systems ENOTSUP == EOPNOTSUPP,
|
||||||
|
// so the compiler complains about a duplicate case.
|
||||||
|
if err == syscall.ENOTSUP {
|
||||||
|
return written, err, written > 0
|
||||||
|
}
|
||||||
|
|
||||||
// Not a retryable error.
|
// Not a retryable error.
|
||||||
return written, err, true
|
return written, err, true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
86
src/net/sendfile_unix_test.go
Normal file
86
src/net/sendfile_unix_test.go
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
// Copyright 2024 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build unix
|
||||||
|
|
||||||
|
package net
|
||||||
|
|
||||||
|
import (
|
||||||
|
"internal/testpty"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"sync"
|
||||||
|
"syscall"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Issue 70763: test that we don't fail on sendfile from a tty.
|
||||||
|
func TestCopyFromTTY(t *testing.T) {
|
||||||
|
pty, ttyName, err := testpty.Open()
|
||||||
|
if err != nil {
|
||||||
|
t.Skipf("skipping test because pty open failed: %v", err)
|
||||||
|
}
|
||||||
|
defer pty.Close()
|
||||||
|
|
||||||
|
// Use syscall.Open so that the tty is blocking.
|
||||||
|
ttyFD, err := syscall.Open(ttyName, syscall.O_RDWR, 0)
|
||||||
|
if err != nil {
|
||||||
|
t.Skipf("skipping test because tty open failed: %v", err)
|
||||||
|
}
|
||||||
|
defer syscall.Close(ttyFD)
|
||||||
|
|
||||||
|
tty := os.NewFile(uintptr(ttyFD), "tty")
|
||||||
|
defer tty.Close()
|
||||||
|
|
||||||
|
ln := newLocalListener(t, "tcp")
|
||||||
|
defer ln.Close()
|
||||||
|
|
||||||
|
ch := make(chan bool)
|
||||||
|
|
||||||
|
const data = "data\n"
|
||||||
|
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
defer wg.Wait()
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
conn, err := ln.Accept()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
buf := make([]byte, len(data))
|
||||||
|
if _, err := io.ReadFull(conn, buf); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ch <- true
|
||||||
|
}()
|
||||||
|
|
||||||
|
conn, err := Dial("tcp", ln.Addr().String())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
if _, err := pty.Write([]byte(data)); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
<-ch
|
||||||
|
if err := pty.Close(); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
lr := io.LimitReader(tty, int64(len(data)))
|
||||||
|
if _, err := io.Copy(conn, lr); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue