...
1
2
3
4
5
6
7 package unix_test
8
9 import (
10 "io"
11 "net"
12 "os"
13 "path/filepath"
14 "testing"
15
16 "golang.org/x/sys/unix"
17 )
18
19 func TestSendfile(t *testing.T) {
20
21 name := filepath.Join(t.TempDir(), "source")
22 const contents = "contents"
23 err := os.WriteFile(name, []byte(contents), 0666)
24 if err != nil {
25 t.Fatal(err)
26 }
27
28 done := make(chan bool)
29
30
31 ln, err := net.Listen("tcp", "127.0.0.1:0")
32 if err != nil {
33 t.Skipf("listen failed: %s\n", err)
34 }
35 defer ln.Close()
36 go func() {
37 conn, err := ln.Accept()
38 if err != nil {
39 t.Errorf("failed to accept: %v", err)
40 return
41 }
42 defer conn.Close()
43 b, err := io.ReadAll(conn)
44 if err != nil {
45 t.Errorf("failed to read: %v", err)
46 return
47 }
48 if string(b) != contents {
49 t.Errorf("contents not transmitted: got %s (len=%d), want %s", string(b), len(b), contents)
50 }
51 done <- true
52 }()
53
54
55 src, err := os.Open(name)
56 if err != nil {
57 t.Fatal(err)
58 }
59
60
61 conn, err := net.Dial("tcp", ln.Addr().String())
62 if err != nil {
63 t.Fatal(err)
64 }
65 file, err := conn.(*net.TCPConn).File()
66 if err != nil {
67 t.Fatal(err)
68 }
69 var off int64
70 n, err := unix.Sendfile(int(file.Fd()), int(src.Fd()), &off, len(contents))
71 if err != nil {
72 t.Errorf("Sendfile failed %s\n", err)
73 }
74 if n != len(contents) {
75 t.Errorf("written count wrong: want %d, got %d", len(contents), n)
76 }
77
78
79
80
81 if off != 0 && off != int64(len(contents)) {
82 t.Errorf("offset wrong: god %d, want %d or %d", off, 0, len(contents))
83 }
84
85 pos, err := src.Seek(0, 1)
86 if err != nil {
87 t.Errorf("can't get cursor position %s\n", err)
88 }
89 if pos != 0 {
90 t.Errorf("cursor position wrong: got %d, want 0", pos)
91 }
92
93 file.Close()
94 conn.Close()
95
96
97 <-done
98 }
99
View as plain text