mirror of
https://github.com/golang/go
synced 2024-11-27 04:31:21 -07:00
412f659280
We were accidentally ignoring any error returned by poll.SendFile. Noticed by reading the code. It could only change behavior if the sendfile system call both wrote some bytes and returned an error. Change-Id: I0693d6ec0a30f5a86b78d38793899ca29fb9e156 Reviewed-on: https://go-review.googlesource.com/c/164760 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
54 lines
1.1 KiB
Go
54 lines
1.1 KiB
Go
// Copyright 2011 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.
|
|
|
|
package net
|
|
|
|
import (
|
|
"internal/poll"
|
|
"io"
|
|
"os"
|
|
)
|
|
|
|
// sendFile copies the contents of r to c using the sendfile
|
|
// system call to minimize copies.
|
|
//
|
|
// if handled == true, sendFile returns the number of bytes copied and any
|
|
// non-EOF error.
|
|
//
|
|
// if handled == false, sendFile performed no work.
|
|
func sendFile(c *netFD, r io.Reader) (written int64, err error, handled bool) {
|
|
var remain int64 = 1 << 62 // by default, copy until EOF
|
|
|
|
lr, ok := r.(*io.LimitedReader)
|
|
if ok {
|
|
remain, r = lr.N, lr.R
|
|
if remain <= 0 {
|
|
return 0, nil, true
|
|
}
|
|
}
|
|
f, ok := r.(*os.File)
|
|
if !ok {
|
|
return 0, nil, false
|
|
}
|
|
|
|
sc, err := f.SyscallConn()
|
|
if err != nil {
|
|
return 0, nil, false
|
|
}
|
|
|
|
var werr error
|
|
err = sc.Read(func(fd uintptr) bool {
|
|
written, werr = poll.SendFile(&c.pfd, int(fd), remain)
|
|
return true
|
|
})
|
|
if err == nil {
|
|
err = werr
|
|
}
|
|
|
|
if lr != nil {
|
|
lr.N = remain - written
|
|
}
|
|
return written, wrapSyscallError("sendfile", err), written > 0
|
|
}
|