src.elv.sh@v0.21.0-dev.0.20240515223629-06979efb9a2a/pkg/eval/interrupts.go (about)

     1  package eval
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"os"
     7  	"os/signal"
     8  	"syscall"
     9  )
    10  
    11  // ErrInterrupted is thrown when the execution is interrupted by a signal.
    12  var ErrInterrupted = errors.New("interrupted")
    13  
    14  // ListenInterrupts returns a Context that is canceled when SIGINT or SIGQUIT
    15  // has been received by the process. It also returns a function to cancel the
    16  // Context, which should be called when it is no longer needed.
    17  func ListenInterrupts() (context.Context, func()) {
    18  	ctx, cancel := context.WithCancel(context.Background())
    19  
    20  	sigCh := make(chan os.Signal, 1)
    21  	signal.Notify(sigCh, syscall.SIGINT, syscall.SIGQUIT)
    22  
    23  	go func() {
    24  		select {
    25  		case <-sigCh:
    26  			cancel()
    27  		case <-ctx.Done():
    28  		}
    29  		signal.Stop(sigCh)
    30  	}()
    31  
    32  	return ctx, func() {
    33  		cancel()
    34  	}
    35  }