github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/net/sendfile_linux.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 package net 6 7 import ( 8 "internal/poll" 9 "io" 10 "os" 11 ) 12 13 // sendFile copies the contents of r to c using the sendfile 14 // system call to minimize copies. 15 // 16 // if handled == true, sendFile returns the number (potentially zero) of bytes 17 // copied and any non-EOF error. 18 // 19 // if handled == false, sendFile performed no work. 20 func sendFile(c *netFD, r io.Reader) (written int64, err error, handled bool) { 21 var remain int64 = 1<<63 - 1 // by default, copy until EOF 22 23 lr, ok := r.(*io.LimitedReader) 24 if ok { 25 remain, r = lr.N, lr.R 26 if remain <= 0 { 27 return 0, nil, true 28 } 29 } 30 f, ok := r.(*os.File) 31 if !ok { 32 return 0, nil, false 33 } 34 35 sc, err := f.SyscallConn() 36 if err != nil { 37 return 0, nil, false 38 } 39 40 var werr error 41 err = sc.Read(func(fd uintptr) bool { 42 written, werr, handled = poll.SendFile(&c.pfd, int(fd), remain) 43 return true 44 }) 45 if err == nil { 46 err = werr 47 } 48 49 if lr != nil { 50 lr.N = remain - written 51 } 52 return written, wrapSyscallError("sendfile", err), handled 53 }