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