...

Source file src/net/sendfile_linux.go

     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 of bytes copied and any
    17	// 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 << 62 // 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 = 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), written > 0
    53	}
    54	

View as plain text