github.com/containers/podman/v4@v4.9.4/pkg/signal/signal_common.go (about)

     1  package signal
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"os/signal"
     7  	"strconv"
     8  	"strings"
     9  	"syscall"
    10  )
    11  
    12  // Make sure the signal buffer is sufficiently big.
    13  // runc is using the same value.
    14  const SignalBufferSize = 2048
    15  
    16  // ParseSignal translates a string to a valid syscall signal.
    17  // It returns an error if the signal map doesn't include the given signal.
    18  func ParseSignal(rawSignal string) (syscall.Signal, error) {
    19  	s, err := strconv.Atoi(rawSignal)
    20  	if err == nil {
    21  		if s == 0 {
    22  			return -1, fmt.Errorf("invalid signal: %s", rawSignal)
    23  		}
    24  		return syscall.Signal(s), nil
    25  	}
    26  	sig, ok := SignalMap[strings.TrimPrefix(strings.ToUpper(rawSignal), "SIG")]
    27  	if !ok {
    28  		return -1, fmt.Errorf("invalid signal: %s", rawSignal)
    29  	}
    30  	return sig, nil
    31  }
    32  
    33  // ParseSignalNameOrNumber translates a string to a valid syscall signal.  Input
    34  // can be a name or number representation i.e. "KILL" "9".
    35  func ParseSignalNameOrNumber(rawSignal string) (syscall.Signal, error) {
    36  	basename := strings.TrimPrefix(rawSignal, "-")
    37  	s, err := ParseSignal(basename)
    38  	if err == nil {
    39  		return s, nil
    40  	}
    41  	for k, v := range SignalMap {
    42  		if k == strings.ToUpper(basename) {
    43  			return v, nil
    44  		}
    45  	}
    46  	return -1, fmt.Errorf("invalid signal: %s", basename)
    47  }
    48  
    49  // CatchAll catches all signals and relays them to the specified channel.
    50  func CatchAll(sigc chan os.Signal) {
    51  	handledSigs := make([]os.Signal, 0, len(SignalMap))
    52  	for _, s := range SignalMap {
    53  		handledSigs = append(handledSigs, s)
    54  	}
    55  	signal.Notify(sigc, handledSigs...)
    56  }
    57  
    58  // StopCatch stops catching the signals and closes the specified channel.
    59  func StopCatch(sigc chan os.Signal) {
    60  	signal.Stop(sigc)
    61  	close(sigc)
    62  }
    63  
    64  // ParseSysSignalToName translates syscall.Signal to its name in the operating system.
    65  // For example, syscall.Signal(9) will return "KILL" on Linux system.
    66  func ParseSysSignalToName(s syscall.Signal) (string, error) {
    67  	for k, v := range SignalMap {
    68  		if v == s {
    69  			return k, nil
    70  		}
    71  	}
    72  	return "", fmt.Errorf("unknown syscall signal: %s", s)
    73  }