// Package signals catches the signals that end the tool, for the // commands that clean up before they end. package signals import ( "context" "os" "os/signal" "syscall" ) // Context is signal.NotifyContext for SIGINT, SIGTERM and SIGHUP: the // context it returns is cancelled when one of them arrives, and stop // stops catching them. It leaves out any of the three the tool was // started with set to be ignored, as nohup does with SIGHUP, because // catching a signal turns an ignored one back on and would end a run // that was meant to survive it. func Context(parent context.Context) (context.Context, context.CancelFunc) { endings := []os.Signal{syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP} caught := make([]os.Signal, 0, len(endings)) for _, ending := range endings { if !signal.Ignored(ending) { caught = append(caught, ending) } } // Given no signals at all, NotifyContext would catch every one. if len(caught) == 0 { return context.WithCancel(parent) } return signal.NotifyContext(parent, caught...) }