// Copyright 2017 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 (darwin || dragonfly || freebsd || (linux && !android) || netbsd || openbsd) && cgo

// Note that this test does not work on Solaris: issue #22849.
// Don't run the test on Android because at least some versions of the
// C library do not define the posix_openpt function.

package signal_test

import (
	"context"
	"encoding/binary"
	"fmt"
	"internal/syscall/unix"
	"internal/testenv"
	"internal/testpty"
	"os"
	"os/signal"
	"runtime"
	"strconv"
	"syscall"
	"testing"
	"time"
)

const (
	ptyFD     = 3 // child end of pty.
	controlFD = 4 // child end of control pipe.
)

// TestTerminalSignal tests that read from a pseudo-terminal does not return an
// error if the process is SIGSTOP'd and put in the background during the read.
//
// This test simulates stopping a Go process running in a shell with ^Z and
// then resuming with `fg`.
//
// This is a regression test for https://go.dev/issue/22838. On Darwin, PTY
// reads return EINTR when this occurs, and Go should automatically retry.
func TestTerminalSignal(t *testing.T) {
	// This test simulates stopping a Go process running in a shell with ^Z
	// and then resuming with `fg`. This sounds simple, but is actually
	// quite complicated.
	//
	// In principle, what we are doing is:
	// 1. Creating a new PTY parent/child FD pair.
	// 2. Create a child that is in the foreground process group of the PTY, and read() from that process.
	// 3. Stop the child with ^Z.
	// 4. Take over as foreground process group of the PTY from the parent.
	// 5. Make the child foreground process group again.
	// 6. Continue the child.
	//
	// On Darwin, step 4 results in the read() returning EINTR once the
	// process continues. internal/poll should automatically retry the
	// read.
	//
	// These steps are complicated by the rules around foreground process
	// groups. A process group cannot be foreground if it is "orphaned",
	// unless it masks SIGTTOU.  i.e., to be foreground the process group
	// must have a parent process group in the same session or mask SIGTTOU
	// (which we do). An orphaned process group cannot receive
	// terminal-generated SIGTSTP at all.
	//
	// Achieving this requires three processes total:
	// - Top-level process: this is the main test process and creates the
	// pseudo-terminal.
	// - GO_TEST_TERMINAL_SIGNALS=1: This process creates a new process
	// group and session. The PTY is the controlling terminal for this
	// session. This process masks SIGTTOU, making it eligible to be a
	// foreground process group. This process will take over as foreground
	// from subprocess 2 (step 4 above).
	// - GO_TEST_TERMINAL_SIGNALS=2: This process create a child process
	// group of subprocess 1, and is the original foreground process group
	// for the PTY. This subprocess is the one that is SIGSTOP'd.

	if runtime.GOOS == "dragonfly" {
		t.Skip("skipping: wait hangs on dragonfly; see https://go.dev/issue/56132")
	}

	scale := 1
	if s := os.Getenv("GO_TEST_TIMEOUT_SCALE"); s != "" {
		if sc, err := strconv.Atoi(s); err == nil {
			scale = sc
		}
	}
	pause := time.Duration(scale) * 10 * time.Millisecond

	lvl := os.Getenv("GO_TEST_TERMINAL_SIGNALS")
	switch lvl {
	case "":
		// Main test process, run code below.
		break
	case "1":
		runSessionLeader(t, pause)
		panic("unreachable")
	case "2":
		runStoppingChild()
		panic("unreachable")
	default:
		fmt.Fprintf(os.Stderr, "unknown subprocess level %s\n", lvl)
		os.Exit(1)
	}

	t.Parallel()

	pty, procTTYName, err := testpty.Open()
	if err != nil {
		ptyErr := err.(*testpty.PtyError)
		if ptyErr.FuncName == "posix_openpt" && ptyErr.Errno == syscall.EACCES {
			t.Skip("posix_openpt failed with EACCES, assuming chroot and skipping")
		}
		t.Fatal(err)
	}
	defer pty.Close()
	procTTY, err := os.OpenFile(procTTYName, os.O_RDWR, 0)
	if err != nil {
		t.Fatal(err)
	}
	defer procTTY.Close()

	// Control pipe. GO_TEST_TERMINAL_SIGNALS=2 send the PID of
	// GO_TEST_TERMINAL_SIGNALS=3 here. After SIGSTOP, it also writes a
	// byte to indicate that the foreground cycling is complete.
	controlR, controlW, err := os.Pipe()
	if err != nil {
		t.Fatal(err)
	}

	var (
		ctx     = context.Background()
		cmdArgs = []string{"-test.run=^TestTerminalSignal$"}
	)
	if deadline, ok := t.Deadline(); ok {
		d := time.Until(deadline)
		var cancel context.CancelFunc
		ctx, cancel = context.WithTimeout(ctx, d)
		t.Cleanup(cancel)

		// We run the subprocess with an additional 20% margin to allow it to fail
		// and clean up gracefully if it times out.
		cmdArgs = append(cmdArgs, fmt.Sprintf("-test.timeout=%v", d*5/4))
	}

	cmd := testenv.CommandContext(t, ctx, os.Args[0], cmdArgs...)
	cmd.Env = append(os.Environ(), "GO_TEST_TERMINAL_SIGNALS=1")
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout // for logging
	cmd.Stderr = os.Stderr
	cmd.ExtraFiles = []*os.File{procTTY, controlW}
	cmd.SysProcAttr = &syscall.SysProcAttr{
		Setsid:  true,
		Setctty: true,
		Ctty:    ptyFD,
	}

	if err := cmd.Start(); err != nil {
		t.Fatal(err)
	}

	if err := procTTY.Close(); err != nil {
		t.Errorf("closing procTTY: %v", err)
	}

	if err := controlW.Close(); err != nil {
		t.Errorf("closing controlW: %v", err)
	}

	// Wait for first child to send the second child's PID.
	b := make([]byte, 8)
	n, err := controlR.Read(b)
	if err != nil {
		t.Fatalf("error reading child pid: %v\n", err)
	}
	if n != 8 {
		t.Fatalf("unexpected short read n = %d\n", n)
	}
	pid := binary.LittleEndian.Uint64(b[:])
	process, err := os.FindProcess(int(pid))
	if err != nil {
		t.Fatalf("unable to find child process: %v", err)
	}

	// Wait for the third child to write a byte indicating that it is
	// entering the read.
	b = make([]byte, 1)
	_, err = pty.Read(b)
	if err != nil {
		t.Fatalf("error reading from child: %v", err)
	}

	// Give the program time to enter the read call.
	// It doesn't matter much if we occasionally don't wait long enough;
	// we won't be testing what we want to test, but the overall test
	// will pass.
	time.Sleep(pause)

	t.Logf("Sending ^Z...")

	// Send a ^Z to stop the program.
	if _, err := pty.Write([]byte{26}); err != nil {
		t.Fatalf("writing ^Z to pty: %v", err)
	}

	// Wait for subprocess 1 to cycle the foreground process group.
	if _, err := controlR.Read(b); err != nil {
		t.Fatalf("error reading readiness: %v", err)
	}

	t.Logf("Sending SIGCONT...")

	// Restart the stopped program.
	if err := process.Signal(syscall.SIGCONT); err != nil {
		t.Fatalf("Signal(SIGCONT) got err %v want nil", err)
	}

	// Write some data for the program to read, which should cause it to
	// exit.
	if _, err := pty.Write([]byte{'\n'}); err != nil {
		t.Fatalf("writing %q to pty: %v", "\n", err)
	}

	t.Logf("Waiting for exit...")

	if err = cmd.Wait(); err != nil {
		t.Errorf("subprogram failed: %v", err)
	}
}

// GO_TEST_TERMINAL_SIGNALS=1 subprocess above.
func runSessionLeader(t *testing.T, pause time.Duration) {
	// "Attempts to use tcsetpgrp() from a process which is a
	// member of a background process group on a fildes associated
	// with its controlling terminal shall cause the process group
	// to be sent a SIGTTOU signal. If the calling thread is
	// blocking SIGTTOU signals or the process is ignoring SIGTTOU
	// signals, the process shall be allowed to perform the
	// operation, and no signal is sent."
	//  -https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcsetpgrp.html
	//
	// We are changing the terminal to put us in the foreground, so
	// we must ignore SIGTTOU. We are also an orphaned process
	// group (see above), so we must mask SIGTTOU to be eligible to
	// become foreground at all.
	signal.Ignore(syscall.SIGTTOU)

	pty := os.NewFile(ptyFD, "pty")
	controlW := os.NewFile(controlFD, "control-pipe")

	var (
		ctx     = context.Background()
		cmdArgs = []string{"-test.run=^TestTerminalSignal$"}
	)
	if deadline, ok := t.Deadline(); ok {
		d := time.Until(deadline)
		var cancel context.CancelFunc
		ctx, cancel = context.WithTimeout(ctx, d)
		t.Cleanup(cancel)

		// We run the subprocess with an additional 20% margin to allow it to fail
		// and clean up gracefully if it times out.
		cmdArgs = append(cmdArgs, fmt.Sprintf("-test.timeout=%v", d*5/4))
	}

	cmd := testenv.CommandContext(t, ctx, os.Args[0], cmdArgs...)
	cmd.Env = append(os.Environ(), "GO_TEST_TERMINAL_SIGNALS=2")
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.ExtraFiles = []*os.File{pty}
	cmd.SysProcAttr = &syscall.SysProcAttr{
		Foreground: true,
		Ctty:       ptyFD,
	}
	if err := cmd.Start(); err != nil {
		fmt.Fprintf(os.Stderr, "error starting second subprocess: %v\n", err)
		os.Exit(1)
	}

	fn := func() error {
		var b [8]byte
		binary.LittleEndian.PutUint64(b[:], uint64(cmd.Process.Pid))
		_, err := controlW.Write(b[:])
		if err != nil {
			return fmt.Errorf("error writing child pid: %w", err)
		}

		// Wait for stop.
		var status syscall.WaitStatus
		for {
			_, err = syscall.Wait4(cmd.Process.Pid, &status, syscall.WUNTRACED, nil)
			if err != syscall.EINTR {
				break
			}
		}
		if err != nil {
			return fmt.Errorf("error waiting for stop: %w", err)
		}

		if !status.Stopped() {
			return fmt.Errorf("unexpected wait status: %v", status)
		}

		// Take TTY.
		pgrp := int32(syscall.Getpgrp()) // assume that pid_t is int32
		if err := unix.Tcsetpgrp(ptyFD, pgrp); err != nil {
			return fmt.Errorf("error setting tty process group: %w", err)
		}

		// Give the kernel time to potentially wake readers and have
		// them return EINTR (darwin does this).
		time.Sleep(pause)

		// Give TTY back.
		pid := int32(cmd.Process.Pid) // assume that pid_t is int32
		if err := unix.Tcsetpgrp(ptyFD, pid); err != nil {
			return fmt.Errorf("error setting tty process group back: %w", err)
		}

		// Report that we are done and SIGCONT can be sent. Note that
		// the actual byte we send doesn't matter.
		if _, err := controlW.Write(b[:1]); err != nil {
			return fmt.Errorf("error writing readiness: %w", err)
		}

		return nil
	}

	err := fn()
	if err != nil {
		fmt.Fprintf(os.Stderr, "session leader error: %v\n", err)
		cmd.Process.Kill()
		// Wait for exit below.
	}

	werr := cmd.Wait()
	if werr != nil {
		fmt.Fprintf(os.Stderr, "error running second subprocess: %v\n", err)
	}

	if err != nil || werr != nil {
		os.Exit(1)
	}

	os.Exit(0)
}

// GO_TEST_TERMINAL_SIGNALS=2 subprocess above.
func runStoppingChild() {
	pty := os.NewFile(ptyFD, "pty")

	var b [1]byte
	if _, err := pty.Write(b[:]); err != nil {
		fmt.Fprintf(os.Stderr, "error writing byte to PTY: %v\n", err)
		os.Exit(1)
	}

	_, err := pty.Read(b[:])
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	if b[0] == '\n' {
		// This is what we expect
		fmt.Println("read newline")
	} else {
		fmt.Fprintf(os.Stderr, "read 1 unexpected byte: %q\n", b)
		os.Exit(1)
	}
	os.Exit(0)
}
