// Copyright 2020 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.

// +build !plan9,!windows

package main

/*
#include <errno.h>
#include <signal.h>
#include <string.h>

static int clearRestart(int sig) {
	struct sigaction sa;

	memset(&sa, 0, sizeof sa);
	if (sigaction(sig, NULL, &sa) < 0) {
		return errno;
	}
	sa.sa_flags &=~ SA_RESTART;
	if (sigaction(sig, &sa, NULL) < 0) {
		return errno;
	}
	return 0;
}
*/
import "C"

import (
	"bytes"
	"errors"
	"fmt"
	"io"
	"log"
	"net"
	"os"
	"os/exec"
	"os/signal"
	"sync"
	"syscall"
	"time"
)

func init() {
	register("EINTR", EINTR)
	register("Block", Block)
}

// Test various operations when a signal handler is installed without
// the SA_RESTART flag. This tests that the os and net APIs handle EINTR.
func EINTR() {
	if errno := C.clearRestart(C.int(syscall.SIGURG)); errno != 0 {
		log.Fatal(syscall.Errno(errno))
	}
	if errno := C.clearRestart(C.int(syscall.SIGWINCH)); errno != 0 {
		log.Fatal(syscall.Errno(errno))
	}
	if errno := C.clearRestart(C.int(syscall.SIGCHLD)); errno != 0 {
		log.Fatal(syscall.Errno(errno))
	}

	var wg sync.WaitGroup
	testPipe(&wg)
	testNet(&wg)
	testExec(&wg)
	wg.Wait()
	fmt.Println("OK")
}

// spin does CPU bound spinning and allocating for a millisecond,
// to get a SIGURG.
//go:noinline
func spin() (float64, [][]byte) {
	stop := time.Now().Add(time.Millisecond)
	r1 := 0.0
	var r2 [][]byte
	for time.Now().Before(stop) {
		for i := 1; i < 1e6; i++ {
			r1 += r1 / float64(i)
			r2 = append(r2, bytes.Repeat([]byte{byte(i)}, 100))
		}
	}
	return r1, r2
}

// winch sends a few SIGWINCH signals to the process.
func winch() {
	ticker := time.NewTicker(100 * time.Microsecond)
	defer ticker.Stop()
	for n := 10; n > 0; n-- {
		syscall.Kill(0, syscall.SIGWINCH)
		<-ticker.C
	}
}

// sendSomeSignals triggers a few SIGURG and SIGWINCH signals.
func sendSomeSignals() {
	spin()
	winch()
}

// testPipe tests pipe operations.
func testPipe(wg *sync.WaitGroup) {
	r, w, err := os.Pipe()
	if err != nil {
		log.Fatal(err)
	}
	if err := syscall.SetNonblock(int(r.Fd()), false); err != nil {
		log.Fatal(err)
	}
	if err := syscall.SetNonblock(int(w.Fd()), false); err != nil {
		log.Fatal(err)
	}
	wg.Add(2)
	go func() {
		defer wg.Done()
		defer w.Close()
		// Spin before calling Write so that the first ReadFull
		// in the other goroutine will likely be interrupted
		// by a signal.
		sendSomeSignals()
		// This Write will likely be interrupted by a signal
		// as the other goroutine spins in the middle of reading.
		// We write enough data that we should always fill the
		// pipe buffer and need multiple write system calls.
		if _, err := w.Write(bytes.Repeat([]byte{0}, 2<<20)); err != nil {
			log.Fatal(err)
		}
	}()
	go func() {
		defer wg.Done()
		defer r.Close()
		b := make([]byte, 1<<20)
		// This ReadFull will likely be interrupted by a signal,
		// as the other goroutine spins before writing anything.
		if _, err := io.ReadFull(r, b); err != nil {
			log.Fatal(err)
		}
		// Spin after reading half the data so that the Write
		// in the other goroutine will likely be interrupted
		// before it completes.
		sendSomeSignals()
		if _, err := io.ReadFull(r, b); err != nil {
			log.Fatal(err)
		}
	}()
}

// testNet tests network operations.
func testNet(wg *sync.WaitGroup) {
	ln, err := net.Listen("tcp4", "127.0.0.1:0")
	if err != nil {
		if errors.Is(err, syscall.EAFNOSUPPORT) || errors.Is(err, syscall.EPROTONOSUPPORT) {
			return
		}
		log.Fatal(err)
	}
	wg.Add(2)
	go func() {
		defer wg.Done()
		defer ln.Close()
		c, err := ln.Accept()
		if err != nil {
			log.Fatal(err)
		}
		defer c.Close()
		cf, err := c.(*net.TCPConn).File()
		if err != nil {
			log.Fatal(err)
		}
		defer cf.Close()
		if err := syscall.SetNonblock(int(cf.Fd()), false); err != nil {
			log.Fatal(err)
		}
		// See comments in testPipe.
		sendSomeSignals()
		if _, err := cf.Write(bytes.Repeat([]byte{0}, 2<<20)); err != nil {
			log.Fatal(err)
		}
	}()
	go func() {
		defer wg.Done()
		sendSomeSignals()
		c, err := net.Dial("tcp", ln.Addr().String())
		if err != nil {
			log.Fatal(err)
		}
		defer c.Close()
		cf, err := c.(*net.TCPConn).File()
		if err != nil {
			log.Fatal(err)
		}
		defer cf.Close()
		if err := syscall.SetNonblock(int(cf.Fd()), false); err != nil {
			log.Fatal(err)
		}
		// See comments in testPipe.
		b := make([]byte, 1<<20)
		if _, err := io.ReadFull(cf, b); err != nil {
			log.Fatal(err)
		}
		sendSomeSignals()
		if _, err := io.ReadFull(cf, b); err != nil {
			log.Fatal(err)
		}
	}()
}

func testExec(wg *sync.WaitGroup) {
	wg.Add(1)
	go func() {
		defer wg.Done()
		cmd := exec.Command(os.Args[0], "Block")
		cmd.Stderr = new(bytes.Buffer)
		cmd.Stdout = cmd.Stderr
		if err := cmd.Start(); err != nil {
			log.Fatal(err)
		}

		go func() {
			sendSomeSignals()
			if err := cmd.Process.Signal(os.Interrupt); err != nil {
				panic(err)
			}
		}()

		if err := cmd.Wait(); err != nil {
			log.Fatalf("%v:\n%s", err, cmd.Stdout)
		}
	}()
}

// Block blocks until the process receives os.Interrupt.
func Block() {
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	defer signal.Stop(c)
	<-c
}
