1// Copyright 2011 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package net 6 7import ( 8 "internal/poll" 9 "io" 10 "os" 11) 12 13const supportsSendfile = true 14 15// sendFile copies the contents of r to c using the sendfile 16// system call to minimize copies. 17// 18// if handled == true, sendFile returns the number (potentially zero) of bytes 19// copied and any non-EOF error. 20// 21// if handled == false, sendFile performed no work. 22func sendFile(c *netFD, r io.Reader) (written int64, err error, handled bool) { 23 var remain int64 = 1<<63 - 1 // by default, copy until EOF 24 25 lr, ok := r.(*io.LimitedReader) 26 if ok { 27 remain, r = lr.N, lr.R 28 if remain <= 0 { 29 return 0, nil, true 30 } 31 } 32 f, ok := r.(*os.File) 33 if !ok { 34 return 0, nil, false 35 } 36 37 sc, err := f.SyscallConn() 38 if err != nil { 39 return 0, nil, false 40 } 41 42 var werr error 43 err = sc.Read(func(fd uintptr) bool { 44 written, werr, handled = poll.SendFile(&c.pfd, int(fd), remain) 45 return true 46 }) 47 if err == nil { 48 err = werr 49 } 50 51 if lr != nil { 52 lr.N = remain - written 53 } 54 return written, wrapSyscallError("sendfile", err), handled 55} 56