Source file
src/internal/poll/sendfile_windows.go
1
2
3
4
5 package poll
6
7 import (
8 "io"
9 "syscall"
10 )
11
12
13 func SendFile(fd *FD, src syscall.Handle, n int64) (written int64, err error) {
14 if fd.kind == kindPipe {
15
16 return 0, syscall.ESPIPE
17 }
18
19 if err := fd.writeLock(); err != nil {
20 return 0, err
21 }
22 defer fd.writeUnlock()
23
24 o := &fd.wop
25 o.handle = src
26
27
28 curpos, err := syscall.Seek(o.handle, 0, io.SeekCurrent)
29 if err != nil {
30 return 0, err
31 }
32
33 if n <= 0 {
34
35 n, err = syscall.Seek(o.handle, -curpos, io.SeekEnd)
36 if err != nil {
37 return
38 }
39
40 if _, err = syscall.Seek(o.handle, curpos, io.SeekStart); err != nil {
41 return
42 }
43 }
44
45
46
47
48 const maxChunkSizePerCall = int64(0x7fffffff - 1)
49
50 for n > 0 {
51 chunkSize := maxChunkSizePerCall
52 if chunkSize > n {
53 chunkSize = n
54 }
55
56 o.qty = uint32(chunkSize)
57 o.o.Offset = uint32(curpos)
58 o.o.OffsetHigh = uint32(curpos >> 32)
59
60 nw, err := execIO(o, func(o *operation) error {
61 return syscall.TransmitFile(o.fd.Sysfd, o.handle, o.qty, 0, &o.o, nil, syscall.TF_WRITE_BEHIND)
62 })
63 if err != nil {
64 return written, err
65 }
66
67 curpos += int64(nw)
68
69
70
71
72 if _, err = syscall.Seek(o.handle, curpos, io.SeekStart); err != nil {
73 return written, err
74 }
75
76 n -= int64(nw)
77 written += int64(nw)
78 }
79
80 return
81 }
82
View as plain text