...
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 if ft, _ := syscall.GetFileType(src); ft == syscall.FILE_TYPE_PIPE {
19 return 0, syscall.ESPIPE
20 }
21
22 if err := fd.writeLock(); err != nil {
23 return 0, err
24 }
25 defer fd.writeUnlock()
26
27 o := &fd.wop
28 o.handle = src
29
30
31 curpos, err := syscall.Seek(o.handle, 0, io.SeekCurrent)
32 if err != nil {
33 return 0, err
34 }
35
36 if n <= 0 {
37
38 n, err = syscall.Seek(o.handle, -curpos, io.SeekEnd)
39 if err != nil {
40 return
41 }
42
43 if _, err = syscall.Seek(o.handle, curpos, io.SeekStart); err != nil {
44 return
45 }
46 }
47
48
49
50
51 const maxChunkSizePerCall = int64(0x7fffffff - 1)
52
53 for n > 0 {
54 chunkSize := maxChunkSizePerCall
55 if chunkSize > n {
56 chunkSize = n
57 }
58
59 o.qty = uint32(chunkSize)
60 o.o.Offset = uint32(curpos)
61 o.o.OffsetHigh = uint32(curpos >> 32)
62
63 nw, err := execIO(o, func(o *operation) error {
64 return syscall.TransmitFile(o.fd.Sysfd, o.handle, o.qty, 0, &o.o, nil, syscall.TF_WRITE_BEHIND)
65 })
66 if err != nil {
67 return written, err
68 }
69
70 curpos += int64(nw)
71
72
73
74
75 if _, err = syscall.Seek(o.handle, curpos, io.SeekStart); err != nil {
76 return written, err
77 }
78
79 n -= int64(nw)
80 written += int64(nw)
81 }
82
83 return
84 }
85
View as plain text