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 }