github.com/HACKERALERT/Picocrypt/src/external/sys@v0.0.0-20210609020157-e519952f829f/unix/sendfile_test.go (about)

     1  // Copyright 2018 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build (darwin && amd64) || dragonfly || freebsd || linux || solaris
     6  // +build darwin,amd64 dragonfly freebsd linux solaris
     7  
     8  package unix_test
     9  
    10  import (
    11  	"io/ioutil"
    12  	"net"
    13  	"os"
    14  	"path/filepath"
    15  	"testing"
    16  
    17  	"golang.org/x/sys/unix"
    18  )
    19  
    20  func TestSendfile(t *testing.T) {
    21  	// Set up source data file.
    22  	tempDir, err := ioutil.TempDir("", "TestSendfile")
    23  	if err != nil {
    24  		t.Fatal(err)
    25  	}
    26  	defer os.RemoveAll(tempDir)
    27  	name := filepath.Join(tempDir, "source")
    28  	const contents = "contents"
    29  	err = ioutil.WriteFile(name, []byte(contents), 0666)
    30  	if err != nil {
    31  		t.Fatal(err)
    32  	}
    33  
    34  	done := make(chan bool)
    35  
    36  	// Start server listening on a socket.
    37  	ln, err := net.Listen("tcp", "127.0.0.1:0")
    38  	if err != nil {
    39  		t.Skipf("listen failed: %s\n", err)
    40  	}
    41  	defer ln.Close()
    42  	go func() {
    43  		conn, err := ln.Accept()
    44  		if err != nil {
    45  			t.Errorf("failed to accept: %v", err)
    46  			return
    47  		}
    48  		defer conn.Close()
    49  		b, err := ioutil.ReadAll(conn)
    50  		if err != nil {
    51  			t.Errorf("failed to read: %v", err)
    52  			return
    53  		}
    54  		if string(b) != contents {
    55  			t.Errorf("contents not transmitted: got %s (len=%d), want %s", string(b), len(b), contents)
    56  		}
    57  		done <- true
    58  	}()
    59  
    60  	// Open source file.
    61  	src, err := os.Open(name)
    62  	if err != nil {
    63  		t.Fatal(err)
    64  	}
    65  
    66  	// Send source file to server.
    67  	conn, err := net.Dial("tcp", ln.Addr().String())
    68  	if err != nil {
    69  		t.Fatal(err)
    70  	}
    71  	file, err := conn.(*net.TCPConn).File()
    72  	if err != nil {
    73  		t.Fatal(err)
    74  	}
    75  	var off int64
    76  	n, err := unix.Sendfile(int(file.Fd()), int(src.Fd()), &off, len(contents))
    77  	if err != nil {
    78  		t.Errorf("Sendfile failed %s\n", err)
    79  	}
    80  	if n != len(contents) {
    81  		t.Errorf("written count wrong: want %d, got %d", len(contents), n)
    82  	}
    83  	// Note: off is updated on some systems and not others. Oh well.
    84  	// Linux: increments off by the amount sent.
    85  	// Darwin: leaves off unchanged.
    86  	// It would be nice to fix Darwin if we can.
    87  	if off != 0 && off != int64(len(contents)) {
    88  		t.Errorf("offset wrong: god %d, want %d or %d", off, 0, len(contents))
    89  	}
    90  	// The cursor position should be unchanged.
    91  	pos, err := src.Seek(0, 1)
    92  	if err != nil {
    93  		t.Errorf("can't get cursor position %s\n", err)
    94  	}
    95  	if pos != 0 {
    96  		t.Errorf("cursor position wrong: got %d, want 0", pos)
    97  	}
    98  
    99  	file.Close() // Note: required to have the close below really send EOF to the server.
   100  	conn.Close()
   101  
   102  	// Wait for server to close.
   103  	<-done
   104  }