github.com/spotify/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/pkg/net/sendfile_windows.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  	"io"
     9  	"os"
    10  	"syscall"
    11  )
    12  
    13  // sendFile copies the contents of r to c using the TransmitFile
    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  //
    21  // Note that sendfile for windows does not suppport >2GB file.
    22  func sendFile(fd *netFD, r io.Reader) (written int64, err error, handled bool) {
    23  	var n int64 = 0 // by default, copy until EOF
    24  
    25  	lr, ok := r.(*io.LimitedReader)
    26  	if ok {
    27  		n, r = lr.N, lr.R
    28  		if n <= 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  	if err := fd.writeLock(); err != nil {
    38  		return 0, err, true
    39  	}
    40  	defer fd.writeUnlock()
    41  
    42  	o := &fd.wop
    43  	o.qty = uint32(n)
    44  	o.handle = syscall.Handle(f.Fd())
    45  	done, err := wsrv.ExecIO(o, "TransmitFile", func(o *operation) error {
    46  		return syscall.TransmitFile(o.fd.sysfd, o.handle, o.qty, 0, &o.o, nil, syscall.TF_WRITE_BEHIND)
    47  	})
    48  	if err != nil {
    49  		return 0, err, false
    50  	}
    51  	if lr != nil {
    52  		lr.N -= int64(done)
    53  	}
    54  	return int64(done), nil, true
    55  }