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