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