...
1
2
3
4
5
6
7 package poll
8
9 import "syscall"
10
11
12
13 const maxSendfileSize int = 4 << 20
14
15
16 func SendFile(dstFD *FD, src int, pos, remain int64) (written int64, err error, handled bool) {
17 defer func() {
18 TestHookDidSendFile(dstFD, src, written, err, handled)
19 }()
20 if err := dstFD.writeLock(); err != nil {
21 return 0, err, false
22 }
23 defer dstFD.writeUnlock()
24
25 if err := dstFD.pd.prepareWrite(dstFD.isFile); err != nil {
26 return 0, err, false
27 }
28
29 dst := dstFD.Sysfd
30 for remain > 0 {
31 n := maxSendfileSize
32 if int64(n) > remain {
33 n = int(remain)
34 }
35 pos1 := pos
36 n, err = syscall.Sendfile(dst, src, &pos1, n)
37 if n > 0 {
38 pos += int64(n)
39 written += int64(n)
40 remain -= int64(n)
41 }
42 if err == syscall.EINTR {
43 continue
44 }
45
46
47
48
49
50 if err != syscall.EAGAIN {
51 break
52 }
53 if err = dstFD.pd.waitWrite(dstFD.isFile); err != nil {
54 break
55 }
56 }
57 handled = written != 0 || (err != syscall.ENOSYS && err != syscall.EINVAL)
58 return
59 }
60
View as plain text