60 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			60 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package commands
 | |
| 
 | |
| import (
 | |
| 	gocontext "context"
 | |
| 	"fmt"
 | |
| 	"os"
 | |
| 	"os/signal"
 | |
| 	"strconv"
 | |
| 	"strings"
 | |
| 	"syscall"
 | |
| 
 | |
| 	"github.com/containerd/containerd"
 | |
| 	"github.com/sirupsen/logrus"
 | |
| )
 | |
| 
 | |
| type killer interface {
 | |
| 	Kill(gocontext.Context, syscall.Signal, ...containerd.KillOpts) error
 | |
| }
 | |
| 
 | |
| // ForwardAllSignals forwards signals
 | |
| func ForwardAllSignals(ctx gocontext.Context, task killer) chan os.Signal {
 | |
| 	sigc := make(chan os.Signal, 128)
 | |
| 	signal.Notify(sigc)
 | |
| 	go func() {
 | |
| 		for s := range sigc {
 | |
| 			logrus.Debug("forwarding signal ", s)
 | |
| 			if err := task.Kill(ctx, s.(syscall.Signal)); err != nil {
 | |
| 				logrus.WithError(err).Errorf("forward signal %s", s)
 | |
| 			}
 | |
| 		}
 | |
| 	}()
 | |
| 	return sigc
 | |
| }
 | |
| 
 | |
| // StopCatch stops and closes a channel
 | |
| func StopCatch(sigc chan os.Signal) {
 | |
| 	signal.Stop(sigc)
 | |
| 	close(sigc)
 | |
| }
 | |
| 
 | |
| // ParseSignal parses a given string into a syscall.Signal
 | |
| // it checks that the signal exists in the platform-appropriate signalMap
 | |
| func ParseSignal(rawSignal string) (syscall.Signal, error) {
 | |
| 	s, err := strconv.Atoi(rawSignal)
 | |
| 	if err == nil {
 | |
| 		sig := syscall.Signal(s)
 | |
| 		for _, msig := range signalMap {
 | |
| 			if sig == msig {
 | |
| 				return sig, nil
 | |
| 			}
 | |
| 		}
 | |
| 		return -1, fmt.Errorf("unknown signal %q", rawSignal)
 | |
| 	}
 | |
| 	signal, ok := signalMap[strings.TrimPrefix(strings.ToUpper(rawSignal), "SIG")]
 | |
| 	if !ok {
 | |
| 		return -1, fmt.Errorf("unknown signal %q", rawSignal)
 | |
| 	}
 | |
| 	return signal, nil
 | |
| }
 | 
