github.com/icodeface/tls@v0.0.0-20230910023335-34df9250cd12/internal/poll/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 poll 6 7 import "syscall" 8 9 // SendFile wraps the TransmitFile call. 10 func SendFile(fd *FD, src syscall.Handle, n int64) (int64, error) { 11 ft, err := syscall.GetFileType(src) 12 if err != nil { 13 return 0, err 14 } 15 // TransmitFile does not work with pipes 16 if ft == syscall.FILE_TYPE_PIPE { 17 return 0, syscall.ESPIPE 18 } 19 20 if err := fd.writeLock(); err != nil { 21 return 0, err 22 } 23 defer fd.writeUnlock() 24 25 o := &fd.wop 26 o.qty = uint32(n) 27 o.handle = src 28 29 // TODO(brainman): skip calling syscall.Seek if OS allows it 30 curpos, err := syscall.Seek(o.handle, 0, 1) 31 if err != nil { 32 return 0, err 33 } 34 35 o.o.Offset = uint32(curpos) 36 o.o.OffsetHigh = uint32(curpos >> 32) 37 38 done, err := wsrv.ExecIO(o, func(o *operation) error { 39 return syscall.TransmitFile(o.fd.Sysfd, o.handle, o.qty, 0, &o.o, nil, syscall.TF_WRITE_BEHIND) 40 }) 41 if err == nil { 42 // Some versions of Windows (Windows 10 1803) do not set 43 // file position after TransmitFile completes. 44 // So just use Seek to set file position. 45 _, err = syscall.Seek(o.handle, curpos+int64(done), 0) 46 } 47 return int64(done), err 48 }