From d455e41777fca6e8a5a79e34a14b8368bc11d9ba Mon Sep 17 00:00:00 2001 From: Shengjing Zhu Date: Sun, 3 Mar 2019 03:44:15 +0800 Subject: [PATCH] unix: add SignalNum to convert signal name to a number Fixes golang/go#28027 Change-Id: Idf8b554e0fd102fd8b2f2f2ea0fa47bf139303da Reviewed-on: https://go-review.googlesource.com/c/164778 Run-TryBot: Tobias Klauser TryBot-Result: Gobot Gobot Reviewed-by: Tobias Klauser --- unix/syscall_unix.go | 18 ++++++++++++++++++ unix/syscall_unix_test.go | 21 +++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/unix/syscall_unix.go b/unix/syscall_unix.go index 33583a22..0f07d29f 100644 --- a/unix/syscall_unix.go +++ b/unix/syscall_unix.go @@ -28,6 +28,11 @@ var ( errENOENT error = syscall.ENOENT ) +var ( + signalNameMapOnce sync.Once + signalNameMap map[string]syscall.Signal +) + // errnoErr returns common boxed Errno values, to prevent // allocations at runtime. func errnoErr(e syscall.Errno) error { @@ -66,6 +71,19 @@ func SignalName(s syscall.Signal) string { return "" } +// SignalNum returns the syscall.Signal for signal named s, +// or 0 if a signal with such name is not found. +// The signal name should start with "SIG". +func SignalNum(s string) syscall.Signal { + signalNameMapOnce.Do(func() { + signalNameMap = make(map[string]syscall.Signal) + for _, signal := range signalList { + signalNameMap[signal.name] = signal.num + } + }) + return signalNameMap[s] +} + // clen returns the index of the first NULL byte in n or len(n) if n contains no NULL byte. func clen(n []byte) int { i := bytes.IndexByte(n, 0) diff --git a/unix/syscall_unix_test.go b/unix/syscall_unix_test.go index f6abe8c0..264305f2 100644 --- a/unix/syscall_unix_test.go +++ b/unix/syscall_unix_test.go @@ -98,6 +98,27 @@ func TestErrnoSignalName(t *testing.T) { } } +func TestSignalNum(t *testing.T) { + testSignals := []struct { + name string + want syscall.Signal + }{ + {"SIGHUP", syscall.SIGHUP}, + {"SIGPIPE", syscall.SIGPIPE}, + {"SIGSEGV", syscall.SIGSEGV}, + {"NONEXISTS", 0}, + } + for _, ts := range testSignals { + t.Run(fmt.Sprintf("%s/%d", ts.name, ts.want), func(t *testing.T) { + got := unix.SignalNum(ts.name) + if got != ts.want { + t.Errorf("SignalNum(%s) returned %d, want %d", ts.name, got, ts.want) + } + }) + + } +} + func TestFcntlInt(t *testing.T) { t.Parallel() file, err := ioutil.TempFile("", "TestFnctlInt")