@@ -295,7 +295,11 @@ func TestPassFD(t *testing.T) {
295
295
defer writeFile.Close()
296
296
defer readFile.Close()
297
297
298
- cmd := exec.Command(os.Args[0], "-test.run=^TestPassFD$", "--", t.TempDir())
298
+ exe, err := os.Executable()
299
+ if err != nil {
300
+ t.Fatal(err)
301
+ }
302
+ cmd := exec.Command(exe, "-test.run=^TestPassFD$", "--", t.TempDir())
299
303
cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
300
304
if lp := os.Getenv("LD_LIBRARY_PATH"); lp != "" {
301
305
cmd.Env = append(cmd.Env, "LD_LIBRARY_PATH="+lp)
@@ -940,7 +944,11 @@ func TestFlock(t *testing.T) {
940
944
p2status := BLOCKED
941
945
done := make(chan bool)
942
946
execP2 := func(isBlock bool) {
943
- cmd := exec.Command(os.Args[0], "-test.run=^TestFlock$", strconv.Itoa(c.p2mode), f.Name())
947
+ exe, err := os.Executable()
948
+ if err != nil {
949
+ t.Fatal(err)
950
+ }
951
+ cmd := exec.Command(exe, "-test.run=^TestFlock$", strconv.Itoa(c.p2mode), f.Name())
944
952
cmd.Env = append(os.Environ(), "TEST_FLOCK_HELPER=1")
945
953
out, _ := cmd.CombinedOutput()
946
954
if p2status, err = strconv.Atoi(string(out)); err != nil {
@@ -1007,7 +1015,11 @@ func TestLegacyFlock(t *testing.T) {
1007
1015
if err != nil {
1008
1016
t.Fatalf("Flock: %s", err.Error())
1009
1017
}
1010
- cmd := exec.Command(os.Args[0], "-test.run=TestLegacyFlock", f.Name())
1018
+ exe, err := os.Executable()
1019
+ if err != nil {
1020
+ t.Fatal(err)
1021
+ }
1022
+ cmd := exec.Command(exe, "-test.run=TestLegacyFlock", f.Name())
1011
1023
cmd.Env = append(os.Environ(), "GO_WANT_HELPER_PROCESS=1")
1012
1024
out, err := cmd.CombinedOutput()
1013
1025
if len(out) > 0 || err != nil {
@@ -2375,7 +2387,11 @@ func TestWait4(t *testing.T) {
2375
2387
2376
2388
for _, c := range testCases {
2377
2389
t.Run(c.name, func(t *testing.T) {
2378
- cmd := exec.Command(os.Args[0], "-test.run=^TestWait4$", fmt.Sprint(c.exitCode))
2390
+ exe, err := os.Executable()
2391
+ if err != nil {
2392
+ t.Fatal(err)
2393
+ }
2394
+ cmd := exec.Command(exe, "-test.run=^TestWait4$", fmt.Sprint(c.exitCode))
2379
2395
cmd.Env = []string{"TEST_WAIT4_HELPER=1"}
2380
2396
if err := cmd.Start(); err != nil {
2381
2397
t.Fatal(err)
@@ -2676,7 +2692,11 @@ func TestMountNamespace(t *testing.T) {
2676
2692
defer os.Remove(f.Name())
2677
2693
f.Close()
2678
2694
2679
- cmd := exec.Command(os.Args[0], "-test.v", "-test.run=^TestMountNamespace$")
2695
+ exe, err := os.Executable()
2696
+ if err != nil {
2697
+ t.Fatal(err)
2698
+ }
2699
+ cmd := exec.Command(exe, "-test.v", "-test.run=^TestMountNamespace$")
2680
2700
cmd.Env = append(os.Environ(), "SETNS_HELPER_PROCESS=1")
2681
2701
cmd.Env = append(cmd.Env, "MNT_NS_FILE="+f.Name())
2682
2702
@@ -3670,7 +3690,11 @@ func TestSetns(t *testing.T) {
3670
3690
}
3671
3691
}
3672
3692
3673
- cmd := exec.Command(os.Args[0], "-test.run=^TestSetns$")
3693
+ exe, err := os.Executable()
3694
+ if err != nil {
3695
+ t.Fatal(err)
3696
+ }
3697
+ cmd := exec.Command(exe, "-test.run=^TestSetns$")
3674
3698
cmd.Env = append(os.Environ(), "SETNS_HELPER_PROCESS=1")
3675
3699
stdin, err := cmd.StdinPipe()
3676
3700
if err != nil {
@@ -3869,5 +3893,126 @@ func TestTty(t *testing.T) {
3869
3893
3870
3894
if !bytes.Equal(text, buffer[:n]) {
3871
3895
t.Fatalf("Expected %+v, read %+v\n", text, buffer[:n])
3896
+
3897
+ }
3898
+
3899
+ }
3900
+
3901
+ func TestSendfile(t *testing.T) {
3902
+ srcContent := "hello, world"
3903
+ srcFile, err := os.Create(filepath.Join(t.TempDir(), "source"))
3904
+ if err != nil {
3905
+ t.Fatal("error: ", err)
3906
+ }
3907
+ defer srcFile.Close()
3908
+
3909
+ dstFile, err := os.Create(filepath.Join(t.TempDir(), "dst"))
3910
+ if err != nil {
3911
+ t.Fatal("error: ", err)
3912
+ }
3913
+ defer dstFile.Close()
3914
+
3915
+ err = os.WriteFile(srcFile.Name(), []byte(srcContent), 0644)
3916
+ if err != nil {
3917
+ t.Fatal("error: ", err)
3918
+ }
3919
+
3920
+ n, err := unix.Sendfile(int(dstFile.Fd()), int(srcFile.Fd()), nil, len(srcContent))
3921
+ if n != len(srcContent) {
3922
+ t.Fatal("error: mismatch content length want ", len(srcContent), " got ", n)
3923
+ }
3924
+ if err != nil {
3925
+ t.Fatal("error: ", err)
3926
+ }
3927
+
3928
+ b, err := os.ReadFile(dstFile.Name())
3929
+ if err != nil {
3930
+ t.Fatal("error: ", err)
3931
+ }
3932
+
3933
+ content := string(b)
3934
+ if content != srcContent {
3935
+ t.Fatal("content mismatch: ", content, " vs ", srcContent)
3872
3936
}
3873
3937
}
3938
+
3939
+ func TestSendfileSocket(t *testing.T) {
3940
+ // Set up source data file.
3941
+ name := filepath.Join(t.TempDir(), "source")
3942
+ const contents = "contents"
3943
+ err := os.WriteFile(name, []byte(contents), 0666)
3944
+ if err != nil {
3945
+ t.Fatal(err)
3946
+ }
3947
+
3948
+ done := make(chan bool)
3949
+
3950
+ // Start server listening on a socket.
3951
+ ln, err := net.Listen("tcp", "127.0.0.1:0")
3952
+ if err != nil {
3953
+ t.Skipf("listen failed: %s\n", err)
3954
+ }
3955
+ defer ln.Close()
3956
+ go func() {
3957
+ conn, err := ln.Accept()
3958
+ if err != nil {
3959
+ t.Errorf("failed to accept: %v", err)
3960
+ return
3961
+ }
3962
+ defer conn.Close()
3963
+ b, err := io.ReadAll(conn)
3964
+ if err != nil {
3965
+ t.Errorf("failed to read: %v", err)
3966
+ return
3967
+ }
3968
+ if string(b) != contents {
3969
+ t.Errorf("contents not transmitted: got %s (len=%d), want %s", string(b), len(b), contents)
3970
+ }
3971
+ done <- true
3972
+ }()
3973
+
3974
+ // Open source file.
3975
+ src, err := os.Open(name)
3976
+ if err != nil {
3977
+ t.Fatal(err)
3978
+ }
3979
+
3980
+ // Send source file to server.
3981
+ conn, err := net.Dial("tcp", ln.Addr().String())
3982
+ if err != nil {
3983
+ t.Fatal(err)
3984
+ }
3985
+ file, err := conn.(*net.TCPConn).File()
3986
+ if err != nil {
3987
+ t.Fatal(err)
3988
+ }
3989
+ var off int64
3990
+ n, err := unix.Sendfile(int(file.Fd()), int(src.Fd()), &off, len(contents))
3991
+ if err != nil {
3992
+ t.Errorf("Sendfile failed %s\n", err)
3993
+ }
3994
+ if n != len(contents) {
3995
+ t.Errorf("written count wrong: want %d, got %d", len(contents), n)
3996
+ }
3997
+ // Note: off is updated on some systems and not others. Oh well.
3998
+ // Linux: increments off by the amount sent.
3999
+ // Darwin: leaves off unchanged.
4000
+ // It would be nice to fix Darwin if we can.
4001
+ if off != 0 && off != int64(len(contents)) {
4002
+ t.Errorf("offset wrong: god %d, want %d or %d", off, 0, len(contents))
4003
+ }
4004
+ // The cursor position should be unchanged.
4005
+ pos, err := src.Seek(0, 1)
4006
+ if err != nil {
4007
+ t.Errorf("can't get cursor position %s\n", err)
4008
+ }
4009
+ if pos != 0 {
4010
+ t.Errorf("cursor position wrong: got %d, want 0", pos)
4011
+ }
4012
+
4013
+ file.Close() // Note: required to have the close below really send EOF to the server.
4014
+ conn.Close()
4015
+
4016
+ // Wait for server to close.
4017
+ <-done
4018
+ }
0 commit comments