more elaborate signal handling

This commit is contained in:
Qi Xiao 2016-02-03 02:19:09 +01:00
parent 946fa29e9a
commit 2823ffb540
3 changed files with 32 additions and 8 deletions

View File

@ -4,6 +4,7 @@ package edit
import ( import (
"fmt" "fmt"
"os" "os"
"os/signal"
"strings" "strings"
"syscall" "syscall"
@ -57,7 +58,7 @@ type Editor struct {
file *os.File file *os.File
writer *writer writer *writer
reader *Reader reader *Reader
sigs <-chan os.Signal sigs chan os.Signal
histories []string histories []string
store *store.Store store *store.Store
evaler *eval.Evaler evaler *eval.Evaler
@ -151,7 +152,7 @@ func (ed *Editor) nextHistory() bool {
} }
// NewEditor creates an Editor. // 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 seq := -1
if st != nil { if st != nil {
var err error var err error
@ -350,6 +351,22 @@ MainLoop:
goto MainLoop goto MainLoop
case syscall.SIGWINCH: case syscall.SIGWINCH:
continue MainLoop 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: case or := <-ones:
// Alert about error // Alert about error

View File

@ -7,7 +7,6 @@ import (
"os" "os"
"os/signal" "os/signal"
"os/user" "os/user"
"runtime"
"syscall" "syscall"
"github.com/elves/elvish/edit" "github.com/elves/elvish/edit"
@ -16,6 +15,7 @@ import (
"github.com/elves/elvish/osutil" "github.com/elves/elvish/osutil"
"github.com/elves/elvish/parse" "github.com/elves/elvish/parse"
"github.com/elves/elvish/store" "github.com/elves/elvish/store"
"github.com/elves/elvish/sys"
) )
const ( const (
@ -132,11 +132,7 @@ var usage = `Usage:
func rescue() { func rescue() {
r := recover() r := recover()
if r != nil { if r != nil {
buf := make([]byte, 1024) sys.DumpStack()
for runtime.Stack(buf, true) == cap(buf) {
buf = make([]byte, cap(buf)*2)
}
print(string(buf))
println("execing recovery shell /bin/sh") println("execing recovery shell /bin/sh")
syscall.Exec("/bin/sh", []string{}, os.Environ()) syscall.Exec("/bin/sh", []string{}, os.Environ())
} }

11
sys/trace.go Normal file
View File

@ -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))
}