@@ -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