From 2823ffb5405ea116b984b7429b2a4ca6f3c36a7c Mon Sep 17 00:00:00 2001 From: Qi Xiao Date: Wed, 3 Feb 2016 02:19:09 +0100 Subject: [PATCH] more elaborate signal handling --- edit/editor.go | 21 +++++++++++++++++++-- main.go | 8 ++------ sys/trace.go | 11 +++++++++++ 3 files changed, 32 insertions(+), 8 deletions(-) create mode 100644 sys/trace.go diff --git a/edit/editor.go b/edit/editor.go index bcd74ddd..a1861df0 100644 --- a/edit/editor.go +++ b/edit/editor.go @@ -4,6 +4,7 @@ package edit import ( "fmt" "os" + "os/signal" "strings" "syscall" @@ -57,7 +58,7 @@ type Editor struct { file *os.File writer *writer reader *Reader - sigs <-chan os.Signal + sigs chan os.Signal histories []string store *store.Store evaler *eval.Evaler @@ -151,7 +152,7 @@ func (ed *Editor) nextHistory() bool { } // NewEditor creates an Editor. -func NewEditor(file *os.File, sigs <-chan os.Signal, ev *eval.Evaler, st *store.Store) *Editor { +func NewEditor(file *os.File, sigs chan os.Signal, ev *eval.Evaler, st *store.Store) *Editor { seq := -1 if st != nil { var err error @@ -350,6 +351,22 @@ MainLoop: goto MainLoop case syscall.SIGWINCH: continue MainLoop + case syscall.SIGQUIT: + // Emulate default behavior + sys.DumpStack() + os.Exit(1) + default: + // Other signals: turn off signal catching, and resend + signal.Stop(ed.sigs) + p, err := os.FindProcess(os.Getpid()) + if err != nil { + panic(err) + } + err = p.Signal(sig) + if err != nil { + panic(err) + } + signal.Notify(ed.sigs) } case or := <-ones: // Alert about error diff --git a/main.go b/main.go index 286fb3f4..b36f7ca1 100644 --- a/main.go +++ b/main.go @@ -7,7 +7,6 @@ import ( "os" "os/signal" "os/user" - "runtime" "syscall" "github.com/elves/elvish/edit" @@ -16,6 +15,7 @@ import ( "github.com/elves/elvish/osutil" "github.com/elves/elvish/parse" "github.com/elves/elvish/store" + "github.com/elves/elvish/sys" ) const ( @@ -132,11 +132,7 @@ var usage = `Usage: func rescue() { r := recover() if r != nil { - buf := make([]byte, 1024) - for runtime.Stack(buf, true) == cap(buf) { - buf = make([]byte, cap(buf)*2) - } - print(string(buf)) + sys.DumpStack() println("execing recovery shell /bin/sh") syscall.Exec("/bin/sh", []string{}, os.Environ()) } diff --git a/sys/trace.go b/sys/trace.go new file mode 100644 index 00000000..7a6930be --- /dev/null +++ b/sys/trace.go @@ -0,0 +1,11 @@ +package sys + +import "runtime" + +func DumpStack() { + buf := make([]byte, 1024) + for runtime.Stack(buf, true) == cap(buf) { + buf = make([]byte, cap(buf)*2) + } + print(string(buf)) +}