Skip to content
Snippets Groups Projects
sendfile_unix_test.go 1.55 KiB
Newer Older
  • Learn to ignore specific revisions
  • // Copyright 2024 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 net
    
    import (
    	"internal/testpty"
    	"io"
    	"os"
    	"sync"
    	"syscall"
    	"testing"
    )
    
    // Issue 70763: test that we don't fail on sendfile from a tty.
    func TestCopyFromTTY(t *testing.T) {
    	pty, ttyName, err := testpty.Open()
    	if err != nil {
    		t.Skipf("skipping test because pty open failed: %v", err)
    	}
    	defer pty.Close()
    
    	// Use syscall.Open so that the tty is blocking.
    	ttyFD, err := syscall.Open(ttyName, syscall.O_RDWR, 0)
    	if err != nil {
    		t.Skipf("skipping test because tty open failed: %v", err)
    	}
    	defer syscall.Close(ttyFD)
    
    	tty := os.NewFile(uintptr(ttyFD), "tty")
    	defer tty.Close()
    
    	ln := newLocalListener(t, "tcp")
    	defer ln.Close()
    
    	ch := make(chan bool)
    
    	const data = "data\n"
    
    	var wg sync.WaitGroup
    	defer wg.Wait()
    
    	wg.Add(1)
    	go func() {
    		defer wg.Done()
    		conn, err := ln.Accept()
    		if err != nil {
    			t.Error(err)
    			return
    		}
    		defer conn.Close()
    
    		buf := make([]byte, len(data))
    		if _, err := io.ReadFull(conn, buf); err != nil {
    			t.Error(err)
    		}
    
    		ch <- true
    	}()
    
    	conn, err := Dial("tcp", ln.Addr().String())
    	if err != nil {
    		t.Fatal(err)
    	}
    	defer conn.Close()
    
    	wg.Add(1)
    	go func() {
    		defer wg.Done()
    		if _, err := pty.Write([]byte(data)); err != nil {
    			t.Error(err)
    		}
    		<-ch
    		if err := pty.Close(); err != nil {
    			t.Error(err)
    		}
    	}()
    
    	lr := io.LimitReader(tty, int64(len(data)))
    	if _, err := io.Copy(conn, lr); err != nil {
    		t.Error(err)
    	}
    }