-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsendfile.go
More file actions
executable file
·46 lines (41 loc) · 1.09 KB
/
Copy pathsendfile.go
File metadata and controls
executable file
·46 lines (41 loc) · 1.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// Copyright (c) 2020 Meng Huang (mhboy@outlook.com)
// This package is licensed under a MIT license that can be found in the LICENSE file.
// Package sendfile wraps the sendfile system call.
package sendfile
import (
"github.com/hslam/mmap"
"net"
"syscall"
)
const (
// maxSendfileSize is the largest chunk size we ask the kernel to copy at a time.
maxSendfileSize int = 4 << 20
// maxBufferSize is the largest chunk size we ask the buffer to copy at a time.
maxBufferSize int = 64 << 10
)
func sendFile(conn net.Conn, src int, pos, remain int64, maxSize int) (written int64, err error) {
var b []byte
for remain > 0 {
n := maxSize
if int(remain) < maxSize {
n = int(remain)
}
offset := mmap.Offset(pos)
rel := pos - offset
b, err = mmap.Open(src, offset, int(rel)+n, mmap.READ)
if err != nil {
return
}
n, errno := conn.Write(b[rel : rel+int64(n)])
mmap.Munmap(b)
if n > 0 {
pos += int64(n)
written += int64(n)
remain -= int64(n)
} else if (n == 0 && errno == nil) || (errno != nil && errno != syscall.EAGAIN) {
err = errno
break
}
}
return written, err
}