summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Heon <mheon@redhat.com>2020-05-28 14:12:19 -0400
committerMatthew Heon <mheon@redhat.com>2020-05-28 14:26:36 -0400
commite0eb6022b32f4261dbd5b78d958afc15ec2af297 (patch)
treeec86bfe91fd45d20d67619d4d9b5a3a70c033ad0
parente704da0c520bfc1d8e0462983e8470040a2fda9d (diff)
downloadpodman-e0eb6022b32f4261dbd5b78d958afc15ec2af297.tar.gz
podman-e0eb6022b32f4261dbd5b78d958afc15ec2af297.tar.bz2
podman-e0eb6022b32f4261dbd5b78d958afc15ec2af297.zip
Ensure that signal names can be parsed on Windows
To ensure the Windows and OS X remote clients can properly parse container stop signal (when given as a name e.g. SIGTERM) and set it in SpecGen, we need access to a list of Linux signal names and the numbers they map to that is available on non-Linux OSes. Fortunately, these are ABI constants that are extremely unlikely to change, so we can just take the existing constant definitions from the library and use them. The signal numbers used here are sourced from AMD64, but should be the same for every architecture that is not Alpha, SPARC, MIPS, and PA-RISC. So `podman run --stop-signal SIGTTOU` from a Windows client to a Podman service on a SPARC host will set an incorrect stop signal, but I don't think this is a large problem. Signed-off-by: Matthew Heon <mheon@redhat.com>
-rw-r--r--pkg/signal/signal_common.go41
-rw-r--r--pkg/signal/signal_linux.go36
-rw-r--r--pkg/signal/signal_unsupported.go89
3 files changed, 118 insertions, 48 deletions
diff --git a/pkg/signal/signal_common.go b/pkg/signal/signal_common.go
new file mode 100644
index 000000000..8ff4b4dbf
--- /dev/null
+++ b/pkg/signal/signal_common.go
@@ -0,0 +1,41 @@
+package signal
+
+import (
+ "fmt"
+ "strconv"
+ "strings"
+ "syscall"
+)
+
+// ParseSignal translates a string to a valid syscall signal.
+// It returns an error if the signal map doesn't include the given signal.
+func ParseSignal(rawSignal string) (syscall.Signal, error) {
+ s, err := strconv.Atoi(rawSignal)
+ if err == nil {
+ if s == 0 {
+ return -1, fmt.Errorf("invalid signal: %s", rawSignal)
+ }
+ return syscall.Signal(s), nil
+ }
+ sig, ok := signalMap[strings.TrimPrefix(strings.ToUpper(rawSignal), "SIG")]
+ if !ok {
+ return -1, fmt.Errorf("invalid signal: %s", rawSignal)
+ }
+ return sig, nil
+}
+
+// ParseSignalNameOrNumber translates a string to a valid syscall signal. Input
+// can be a name or number representation i.e. "KILL" "9"
+func ParseSignalNameOrNumber(rawSignal string) (syscall.Signal, error) {
+ basename := strings.TrimPrefix(rawSignal, "-")
+ s, err := ParseSignal(basename)
+ if err == nil {
+ return s, nil
+ }
+ for k, v := range signalMap {
+ if k == strings.ToUpper(basename) {
+ return v, nil
+ }
+ }
+ return -1, fmt.Errorf("invalid signal: %s", basename)
+}
diff --git a/pkg/signal/signal_linux.go b/pkg/signal/signal_linux.go
index e6e0f1ca1..6eebf7e5a 100644
--- a/pkg/signal/signal_linux.go
+++ b/pkg/signal/signal_linux.go
@@ -8,11 +8,8 @@ package signal
// NOTE: this package has originally been copied from github.com/docker/docker.
import (
- "fmt"
"os"
"os/signal"
- "strconv"
- "strings"
"syscall"
"golang.org/x/sys/unix"
@@ -94,23 +91,6 @@ var signalMap = map[string]syscall.Signal{
"RTMAX": sigrtmax,
}
-// ParseSignal translates a string to a valid syscall signal.
-// It returns an error if the signal map doesn't include the given signal.
-func ParseSignal(rawSignal string) (syscall.Signal, error) {
- s, err := strconv.Atoi(rawSignal)
- if err == nil {
- if s == 0 {
- return -1, fmt.Errorf("invalid signal: %s", rawSignal)
- }
- return syscall.Signal(s), nil
- }
- sig, ok := signalMap[strings.TrimPrefix(strings.ToUpper(rawSignal), "SIG")]
- if !ok {
- return -1, fmt.Errorf("invalid signal: %s", rawSignal)
- }
- return sig, nil
-}
-
// CatchAll catches all signals and relays them to the specified channel.
func CatchAll(sigc chan os.Signal) {
var handledSigs []os.Signal
@@ -125,19 +105,3 @@ func StopCatch(sigc chan os.Signal) {
signal.Stop(sigc)
close(sigc)
}
-
-// ParseSignalNameOrNumber translates a string to a valid syscall signal. Input
-// can be a name or number representation i.e. "KILL" "9"
-func ParseSignalNameOrNumber(rawSignal string) (syscall.Signal, error) {
- basename := strings.TrimPrefix(rawSignal, "-")
- s, err := ParseSignal(basename)
- if err == nil {
- return s, nil
- }
- for k, v := range signalMap {
- if k == strings.ToUpper(basename) {
- return v, nil
- }
- }
- return -1, fmt.Errorf("invalid signal: %s", basename)
-}
diff --git a/pkg/signal/signal_unsupported.go b/pkg/signal/signal_unsupported.go
index f946d802d..9d1733c02 100644
--- a/pkg/signal/signal_unsupported.go
+++ b/pkg/signal/signal_unsupported.go
@@ -4,17 +4,88 @@
package signal
import (
- "fmt"
"os"
"syscall"
)
-const SIGWINCH = syscall.Signal(0xff)
+const (
+ sigrtmin = 34
+ sigrtmax = 64
-// ParseSignal translates a string to a valid syscall signal.
-// It returns an error if the signal map doesn't include the given signal.
-func ParseSignal(rawSignal string) (syscall.Signal, error) {
- return 0, fmt.Errorf("unsupported on non-linux platforms")
+ SIGWINCH = syscall.Signal(0xff)
+)
+
+// signalMap is a map of Linux signals.
+// These constants are sourced from the Linux version of golang.org/x/sys/unix
+// (I don't see much risk of this changing).
+// This should work as long as Podman only runs containers on Linux, which seems
+// a safe assumption for now.
+var signalMap = map[string]syscall.Signal{
+ "ABRT": syscall.Signal(0x6),
+ "ALRM": syscall.Signal(0xe),
+ "BUS": syscall.Signal(0x7),
+ "CHLD": syscall.Signal(0x11),
+ "CLD": syscall.Signal(0x11),
+ "CONT": syscall.Signal(0x12),
+ "FPE": syscall.Signal(0x8),
+ "HUP": syscall.Signal(0x1),
+ "ILL": syscall.Signal(0x4),
+ "INT": syscall.Signal(0x2),
+ "IO": syscall.Signal(0x1d),
+ "IOT": syscall.Signal(0x6),
+ "KILL": syscall.Signal(0x9),
+ "PIPE": syscall.Signal(0xd),
+ "POLL": syscall.Signal(0x1d),
+ "PROF": syscall.Signal(0x1b),
+ "PWR": syscall.Signal(0x1e),
+ "QUIT": syscall.Signal(0x3),
+ "SEGV": syscall.Signal(0xb),
+ "STKFLT": syscall.Signal(0x10),
+ "STOP": syscall.Signal(0x13),
+ "SYS": syscall.Signal(0x1f),
+ "TERM": syscall.Signal(0xf),
+ "TRAP": syscall.Signal(0x5),
+ "TSTP": syscall.Signal(0x14),
+ "TTIN": syscall.Signal(0x15),
+ "TTOU": syscall.Signal(0x16),
+ "URG": syscall.Signal(0x17),
+ "USR1": syscall.Signal(0xa),
+ "USR2": syscall.Signal(0xc),
+ "VTALRM": syscall.Signal(0x1a),
+ "WINCH": syscall.Signal(0x1c),
+ "XCPU": syscall.Signal(0x18),
+ "XFSZ": syscall.Signal(0x19),
+ "RTMIN": sigrtmin,
+ "RTMIN+1": sigrtmin + 1,
+ "RTMIN+2": sigrtmin + 2,
+ "RTMIN+3": sigrtmin + 3,
+ "RTMIN+4": sigrtmin + 4,
+ "RTMIN+5": sigrtmin + 5,
+ "RTMIN+6": sigrtmin + 6,
+ "RTMIN+7": sigrtmin + 7,
+ "RTMIN+8": sigrtmin + 8,
+ "RTMIN+9": sigrtmin + 9,
+ "RTMIN+10": sigrtmin + 10,
+ "RTMIN+11": sigrtmin + 11,
+ "RTMIN+12": sigrtmin + 12,
+ "RTMIN+13": sigrtmin + 13,
+ "RTMIN+14": sigrtmin + 14,
+ "RTMIN+15": sigrtmin + 15,
+ "RTMAX-14": sigrtmax - 14,
+ "RTMAX-13": sigrtmax - 13,
+ "RTMAX-12": sigrtmax - 12,
+ "RTMAX-11": sigrtmax - 11,
+ "RTMAX-10": sigrtmax - 10,
+ "RTMAX-9": sigrtmax - 9,
+ "RTMAX-8": sigrtmax - 8,
+ "RTMAX-7": sigrtmax - 7,
+ "RTMAX-6": sigrtmax - 6,
+ "RTMAX-5": sigrtmax - 5,
+ "RTMAX-4": sigrtmax - 4,
+ "RTMAX-3": sigrtmax - 3,
+ "RTMAX-2": sigrtmax - 2,
+ "RTMAX-1": sigrtmax - 1,
+ "RTMAX": sigrtmax,
}
// CatchAll catches all signals and relays them to the specified channel.
@@ -26,9 +97,3 @@ func CatchAll(sigc chan os.Signal) {
func StopCatch(sigc chan os.Signal) {
panic("Unsupported on non-linux platforms")
}
-
-// ParseSignalNameOrNumber translates a string to a valid syscall signal. Input
-// can be a name or number representation i.e. "KILL" "9"
-func ParseSignalNameOrNumber(rawSignal string) (syscall.Signal, error) {
- return 0, fmt.Errorf("unsupported on non-linux platforms")
-}