| // 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)) |
| } |
| } |