Source file src/net/sendfile_unix_test.go

     1  // Copyright 2024 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 unix
     6  
     7  package net
     8  
     9  import (
    10  	"internal/testpty"
    11  	"io"
    12  	"os"
    13  	"sync"
    14  	"syscall"
    15  	"testing"
    16  )
    17  
    18  // Issue 70763: test that we don't fail on sendfile from a tty.
    19  func TestCopyFromTTY(t *testing.T) {
    20  	pty, ttyName, err := testpty.Open()
    21  	if err != nil {
    22  		t.Skipf("skipping test because pty open failed: %v", err)
    23  	}
    24  	defer pty.Close()
    25  
    26  	// Use syscall.Open so that the tty is blocking.
    27  	ttyFD, err := syscall.Open(ttyName, syscall.O_RDWR, 0)
    28  	if err != nil {
    29  		t.Skipf("skipping test because tty open failed: %v", err)
    30  	}
    31  	defer syscall.Close(ttyFD)
    32  
    33  	tty := os.NewFile(uintptr(ttyFD), "tty")
    34  	defer tty.Close()
    35  
    36  	ln := newLocalListener(t, "tcp")
    37  	defer ln.Close()
    38  
    39  	ch := make(chan bool)
    40  
    41  	const data = "data\n"
    42  
    43  	var wg sync.WaitGroup
    44  	defer wg.Wait()
    45  
    46  	wg.Add(1)
    47  	go func() {
    48  		defer wg.Done()
    49  		conn, err := ln.Accept()
    50  		if err != nil {
    51  			t.Error(err)
    52  			return
    53  		}
    54  		defer conn.Close()
    55  
    56  		buf := make([]byte, len(data))
    57  		if _, err := io.ReadFull(conn, buf); err != nil {
    58  			t.Error(err)
    59  		}
    60  
    61  		ch <- true
    62  	}()
    63  
    64  	conn, err := Dial("tcp", ln.Addr().String())
    65  	if err != nil {
    66  		t.Fatal(err)
    67  	}
    68  	defer conn.Close()
    69  
    70  	wg.Add(1)
    71  	go func() {
    72  		defer wg.Done()
    73  		if _, err := pty.Write([]byte(data)); err != nil {
    74  			t.Error(err)
    75  		}
    76  		<-ch
    77  		if err := pty.Close(); err != nil {
    78  			t.Error(err)
    79  		}
    80  	}()
    81  
    82  	lr := io.LimitReader(tty, int64(len(data)))
    83  	if _, err := io.Copy(conn, lr); err != nil {
    84  		t.Error(err)
    85  	}
    86  }
    87  

View as plain text