func handleQuit() { quitSigs := make(chan os.Signal) signal.Notify(quitSigs, syscall.SIGQUIT) <-quitSigs fmt.Print(sys.DumpStack()) os.Exit(3) }
func TestAsyncReaderDeadlock(t *testing.T) { done := make(chan struct{}) isatty := sys.IsATTY(1) rand.Seed(time.Now().UTC().UnixNano()) timer := time.NewTimer(DeadlockTimeout) for i := 0; i < DeadlockRun; i++ { if isatty { fmt.Printf("\r%d/%d ", i+1, DeadlockRun) } go f(done) select { case <-done: // no deadlock trigerred case <-timer.C: // deadlock t.Errorf("%s", sys.DumpStack()) t.Fatalf("AsyncReader deadlock trigerred on run %d/%d, stack trace:\n%s", i, DeadlockRun, sys.DumpStack()) } timer.Reset(DeadlockTimeout) } if isatty { fmt.Print("\r \r") } }
func rescue() { r := recover() if r != nil { print(sys.DumpStack()) println("\nexecing recovery shell /bin/sh") syscall.Exec("/bin/sh", []string{"/bin/sh"}, os.Environ()) } }
func handleHupAndQuit() { sigs := make(chan os.Signal) signal.Notify(sigs, syscall.SIGHUP, syscall.SIGQUIT) go func() { for sig := range sigs { fmt.Print(sys.DumpStack()) if sig == syscall.SIGQUIT { os.Exit(3) } } }() }
// ReadLine reads a line interactively. // TODO(xiaq): ReadLine currently handles SIGINT and SIGWINCH and swallows all // other signals. func (ed *Editor) ReadLine(prompt, rprompt func() string) (lr LineRead) { ed.editorState = editorState{active: true} go ed.updateIsExternal() ed.writer.oldBuf.cells = nil ones := ed.reader.Chan() go ed.reader.Run() err := ed.startReadLine() if err != nil { return LineRead{Err: err} } defer ed.finishReadLine(&lr) MainLoop: for { ed.prompt = prompt() ed.rprompt = rprompt() err := ed.refresh() if err != nil { return LineRead{Err: err} } ed.tips = nil select { case sig := <-ed.sigs: // TODO(xiaq): Maybe support customizable handling of signals switch sig { case syscall.SIGINT: // Start over ed.editorState = editorState{savedTermios: ed.savedTermios} goto MainLoop case syscall.SIGWINCH: continue MainLoop case syscall.SIGQUIT: // Emulate default behavior print(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 err := or.Err if err != nil { ed.pushTip(err.Error()) continue } // Ignore bogus CPR if or.CPR != invalidPos { continue } k := or.Key lookupKey: keyBinding, ok := keyBindings[ed.mode] if !ok { ed.pushTip("No binding for current mode") continue } name, bound := keyBinding[k] if !bound { name = keyBinding[DefaultBinding] } ed.lastKey = k builtins[name](ed) act := ed.nextAction ed.nextAction = action{} switch act.actionType { case noAction: continue case reprocessKey: err = ed.refresh() if err != nil { return LineRead{Err: err} } goto lookupKey case exitReadLine: return act.returnValue } } } }