repo_description: The Go programming language
repo_topics: go golang language programming-language
code: // Copyright 2025 The Go Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style
  // license that can be found in the LICENSE file.
  
  //go:build unix
  
  package bufio_test
  
  import (
  	"bufio"
  	"io"
  	"net"
  	"path/filepath"
  	"strings"
  	"sync"
  	"testing"
  )
  
  // TestCopyUnixpacket tests that we can use bufio when copying
  // across a unixpacket socket. This used to fail due to an unnecessary
  // empty Write call that was interpreted as an EOF.
  func TestCopyUnixpacket(t *testing.T) {
  	tmpDir := t.TempDir()
  	socket := filepath.Join(tmpDir, "unixsock")
  
  	// Start a unixpacket server.
  	addr := &net.UnixAddr{
  		Name: socket,
  		Net:  "unixpacket",
  	}
  	server, err := net.ListenUnix("unixpacket", addr)
  	if err != nil {
  		t.Skipf("skipping test because opening a unixpacket socket failed: %v", err)
  	}
  
  	// Start a goroutine for the server to accept one connection
  	// and read all the data sent on the connection,
  	// reporting the number of bytes read on ch.
  	ch := make(chan int, 1)
  	var wg sync.WaitGroup
  	wg.Add(1)
  	go func() {
  		defer wg.Done()
  
  		tot := 0
  		defer func() {
  			ch <- tot
  		}()
  
  		serverConn, err := server.Accept()
  		if err != nil {
  			t.Error(err)
  			return
  		}
  
  		buf := make([]byte, 1024)
  		for {
  			n, err := serverConn.Read(buf)
  			tot += n
  			if err == io.EOF {
  				return
  			}
  			if err != nil {
  				t.Error(err)
  				return
  			}
  		}
  	}()
  
  	clientConn, err := net.DialUnix("unixpacket", nil, addr)
  	if err != nil {
  		// Leaves the server goroutine hanging. Oh well.
  		t.Fatal(err)
  	}
  
  	defer wg.Wait()
  	defer clientConn.Close()
  
  	const data = "data"
  	r := bufio.NewReader(strings.NewReader(data))
  	n, err := io.Copy(clientConn, r)
  	if err != nil {
  		t.Fatal(err)
  	}
  
  	if n != int64(len(data)) {
  		t.Errorf("io.Copy returned %d, want %d", n, len(data))
  	}
  
  	clientConn.Close()
  	tot := <-ch
  
  	if tot != len(data) {
  		t.Errorf("server read %d, want %d", tot, len(data))
  	}
  }
  