signal.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. // Package signal provides helper functions for dealing with signals across
  2. // various operating systems.
  3. package signal
  4. import (
  5. "fmt"
  6. "os"
  7. "os/signal"
  8. "strconv"
  9. "strings"
  10. "syscall"
  11. )
  12. // CatchAll catches all signals and relays them to the specified channel.
  13. // SIGURG is not handled, as it's used by the Go runtime to support
  14. // preemptable system calls.
  15. func CatchAll(sigc chan os.Signal) {
  16. var handledSigs []os.Signal
  17. for n, s := range SignalMap {
  18. if n == "URG" {
  19. // Do not handle SIGURG, as in go1.14+, the go runtime issues
  20. // SIGURG as an interrupt to support preemptable system calls on Linux.
  21. continue
  22. }
  23. handledSigs = append(handledSigs, s)
  24. }
  25. signal.Notify(sigc, handledSigs...)
  26. }
  27. // StopCatch stops catching the signals and closes the specified channel.
  28. func StopCatch(sigc chan os.Signal) {
  29. signal.Stop(sigc)
  30. close(sigc)
  31. }
  32. // ParseSignal translates a string to a valid syscall signal.
  33. // It returns an error if the signal map doesn't include the given signal.
  34. func ParseSignal(rawSignal string) (syscall.Signal, error) {
  35. s, err := strconv.Atoi(rawSignal)
  36. if err == nil {
  37. if s == 0 {
  38. return -1, fmt.Errorf("invalid signal: %s", rawSignal)
  39. }
  40. return syscall.Signal(s), nil
  41. }
  42. signal, ok := SignalMap[strings.TrimPrefix(strings.ToUpper(rawSignal), "SIG")]
  43. if !ok {
  44. return -1, fmt.Errorf("invalid signal: %s", rawSignal)
  45. }
  46. return signal, nil
  47. }
  48. // ValidSignalForPlatform returns true if a signal is valid on the platform
  49. func ValidSignalForPlatform(sig syscall.Signal) bool {
  50. for _, v := range SignalMap {
  51. if v == sig {
  52. return true
  53. }
  54. }
  55. return false
  56. }