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 }