const maxSendfileSize int = 4 << 20
// SendFile wraps the sendfile system call.
-func SendFile(dstFD *FD, src int, remain int64) (int64, error) {
+func SendFile(dstFD *FD, src int, remain int64) (int64, error, bool) {
if err := dstFD.writeLock(); err != nil {
- return 0, err
+ return 0, err, false
}
defer dstFD.writeUnlock()
if err := dstFD.pd.prepareWrite(dstFD.isFile); err != nil {
- return 0, err
+ return 0, err, false
}
dst := dstFD.Sysfd
- var written int64
- var err error
+ var (
+ written int64
+ err error
+ handled = true
+ )
for remain > 0 {
n := maxSendfileSize
if int64(n) > remain {
// support) and syscall.EINVAL (fd types which
// don't implement sendfile)
err = err1
+ handled = false
break
}
}
- return written, err
+ return written, err, handled
}
// 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 == true, sendFile returns the number (potentially zero) 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 werr error
err = sc.Read(func(fd uintptr) bool {
- written, werr = poll.SendFile(&c.pfd, int(fd), remain)
+ written, werr, handled = poll.SendFile(&c.pfd, int(fd), remain)
return true
})
if err == nil {
if lr != nil {
lr.N = remain - written
}
- return written, wrapSyscallError("sendfile", err), written > 0
+ return written, wrapSyscallError("sendfile", err), handled
}