github.com/guyezi/gofrontend@v0.0.0-20200228202240-7a62a49e62c0/libgo/go/net/sendfile_glibc.go (about) 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 5 // +build hurd linux 6 7 package net 8 9 import ( 10 "internal/poll" 11 "io" 12 "os" 13 ) 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 of bytes copied and any 19 // non-EOF error. 20 // 21 // if handled == false, sendFile performed no work. 22 func sendFile(c *netFD, r io.Reader) (written int64, err error, handled bool) { 23 var remain int64 = 1 << 62 // 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 = poll.SendFile(&c.pfd, int(fd), remain) 45 return true 46 }) 47 if werr == nil { 48 werr = err 49 } 50 51 if lr != nil { 52 lr.N = remain - written 53 } 54 return written, wrapSyscallError("sendfile", err), written > 0 55 }