@@ -295,7 +295,11 @@ func TestPassFD(t *testing.T) {
295295 defer writeFile .Close ()
296296 defer readFile .Close ()
297297
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 ())
299303 cmd .Env = []string {"GO_WANT_HELPER_PROCESS=1" }
300304 if lp := os .Getenv ("LD_LIBRARY_PATH" ); lp != "" {
301305 cmd .Env = append (cmd .Env , "LD_LIBRARY_PATH=" + lp )
@@ -940,7 +944,11 @@ func TestFlock(t *testing.T) {
940944 p2status := BLOCKED
941945 done := make (chan bool )
942946 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 ())
944952 cmd .Env = append (os .Environ (), "TEST_FLOCK_HELPER=1" )
945953 out , _ := cmd .CombinedOutput ()
946954 if p2status , err = strconv .Atoi (string (out )); err != nil {
@@ -1007,7 +1015,11 @@ func TestLegacyFlock(t *testing.T) {
10071015 if err != nil {
10081016 t .Fatalf ("Flock: %s" , err .Error ())
10091017 }
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 ())
10111023 cmd .Env = append (os .Environ (), "GO_WANT_HELPER_PROCESS=1" )
10121024 out , err := cmd .CombinedOutput ()
10131025 if len (out ) > 0 || err != nil {
@@ -2375,7 +2387,11 @@ func TestWait4(t *testing.T) {
23752387
23762388 for _ , c := range testCases {
23772389 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 ))
23792395 cmd .Env = []string {"TEST_WAIT4_HELPER=1" }
23802396 if err := cmd .Start (); err != nil {
23812397 t .Fatal (err )
@@ -2676,7 +2692,11 @@ func TestMountNamespace(t *testing.T) {
26762692 defer os .Remove (f .Name ())
26772693 f .Close ()
26782694
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$" )
26802700 cmd .Env = append (os .Environ (), "SETNS_HELPER_PROCESS=1" )
26812701 cmd .Env = append (cmd .Env , "MNT_NS_FILE=" + f .Name ())
26822702
@@ -3670,7 +3690,11 @@ func TestSetns(t *testing.T) {
36703690 }
36713691 }
36723692
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$" )
36743698 cmd .Env = append (os .Environ (), "SETNS_HELPER_PROCESS=1" )
36753699 stdin , err := cmd .StdinPipe ()
36763700 if err != nil {
@@ -3869,5 +3893,126 @@ func TestTty(t *testing.T) {
38693893
38703894 if ! bytes .Equal (text , buffer [:n ]) {
38713895 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 )
38723936 }
38733937}
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