Source file
src/net/sendfile_unix_alt.go
1
2
3
4
5
6
7 package net
8
9 import (
10 "internal/poll"
11 "io"
12 "os"
13 )
14
15
16
17
18
19
20
21
22 func sendFile(c *netFD, r io.Reader) (written int64, err error, handled bool) {
23
24
25
26
27
28 var remain int64 = 0
29
30 lr, ok := r.(*io.LimitedReader)
31 if ok {
32 remain, r = lr.N, lr.R
33 if remain <= 0 {
34 return 0, nil, true
35 }
36 }
37 f, ok := r.(*os.File)
38 if !ok {
39 return 0, nil, false
40 }
41
42 if remain == 0 {
43 fi, err := f.Stat()
44 if err != nil {
45 return 0, err, false
46 }
47
48 remain = fi.Size()
49 }
50
51
52
53
54
55
56 pos, err := f.Seek(0, io.SeekCurrent)
57 if err != nil {
58 return 0, err, false
59 }
60
61 sc, err := f.SyscallConn()
62 if err != nil {
63 return 0, nil, false
64 }
65
66 var werr error
67 err = sc.Read(func(fd uintptr) bool {
68 written, werr = poll.SendFile(&c.pfd, int(fd), pos, remain)
69 return true
70 })
71 if err == nil {
72 err = werr
73 }
74
75 if lr != nil {
76 lr.N = remain - written
77 }
78
79 _, err1 := f.Seek(written, io.SeekCurrent)
80 if err1 != nil && err == nil {
81 return written, err1, written > 0
82 }
83
84 return written, wrapSyscallError("sendfile", err), written > 0
85 }
86
View as plain text