}
}
`
+
+func TestSignalExitStatus(t *testing.T) {
+ testenv.MustHaveGoBuild(t)
+ exe, err := buildTestProg(t, "testprog")
+ if err != nil {
+ t.Fatal(err)
+ }
+ err = testEnv(exec.Command(exe, "SignalExitStatus")).Run()
+ if err == nil {
+ t.Error("test program succeeded unexpectedly")
+ } else if ee, ok := err.(*exec.ExitError); !ok {
+ t.Errorf("error (%v) has type %T; expected exec.ExitError", err, err)
+ } else if ws, ok := ee.Sys().(syscall.WaitStatus); !ok {
+ t.Errorf("error.Sys (%v) has type %T; expected syscall.WaitStatus", ee.Sys(), ee.Sys())
+ } else if !ws.Signaled() || ws.Signal() != syscall.SIGTERM {
+ t.Errorf("got %v; expected SIGTERM", ee)
+ }
+}
throw("too many writes on closed pipe")
}
+func dieFromSignal(sig int32) {
+ exit(2)
+}
+
func sigpanic() {
g := getg()
if !canpanic(g) {
if sigsend(_SIGPIPE) {
return
}
- setsig(_SIGPIPE, _SIG_DFL, false)
- raise(_SIGPIPE)
+ dieFromSignal(_SIGPIPE)
+}
+
+// dieFromSignal kills the program with a signal.
+// This provides the expected exit status for the shell.
+// This is only called with fatal signals expected to kill the process.
+func dieFromSignal(sig int32) {
+ setsig(sig, _SIG_DFL, false)
+ updatesigmask(sigmask{})
+ raise(sig)
+ // That should have killed us; call exit just in case.
+ exit(2)
}
// raisebadsignal is called when a signal is received on a non-Go
}
}
- updatesigmask(sigmask{})
- setsig(_SIGABRT, _SIG_DFL, false)
- raise(_SIGABRT)
+ dieFromSignal(_SIGABRT)
}
// ensureSigM starts one global, sleeping thread to make sure at least one thread
}
if flags&_SigKill != 0 {
- exit(2)
+ dieFromSignal(int32(sig))
}
if flags&_SigThrow == 0 {
}
if flags&_SigKill != 0 {
- exit(2)
+ dieFromSignal(int32(sig))
}
if flags&_SigThrow == 0 {
}
if flags&_SigKill != 0 {
- exit(2)
+ dieFromSignal(int32(sig))
}
if flags&_SigThrow == 0 {
}
if flags&_SigKill != 0 {
- exit(2)
+ dieFromSignal(int32(sig))
}
if flags&_SigThrow == 0 {
}
if flags&_SigKill != 0 {
- exit(2)
+ dieFromSignal(int32(sig))
}
if flags&_SigThrow == 0 {
}
if flags&_SigKill != 0 {
- exit(2)
+ dieFromSignal(int32(sig))
}
if flags&_SigThrow == 0 {
--- /dev/null
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !windows,!plan9,!nacl
+
+package main
+
+import "syscall"
+
+func init() {
+ register("SignalExitStatus", SignalExitStatus)
+}
+
+func SignalExitStatus() {
+ syscall.Kill(syscall.Getpid(), syscall.SIGTERM)
+}