diff options
author | Felix Lange <fjl@twurst.com> | 2015-05-27 06:52:02 +0800 |
---|---|---|
committer | Felix Lange <fjl@twurst.com> | 2015-05-27 06:54:48 +0800 |
commit | 9253fc337e4f36029f90f31b1b4e116d0a77ae05 (patch) | |
tree | a45d322eb3ec37a1b278370ce0eecb8e4aaad275 | |
parent | 612f01400f59b0b4d0db9f9ceaa38f45805ea89e (diff) | |
download | dexon-9253fc337e4f36029f90f31b1b4e116d0a77ae05.tar dexon-9253fc337e4f36029f90f31b1b4e116d0a77ae05.tar.gz dexon-9253fc337e4f36029f90f31b1b4e116d0a77ae05.tar.bz2 dexon-9253fc337e4f36029f90f31b1b4e116d0a77ae05.tar.lz dexon-9253fc337e4f36029f90f31b1b4e116d0a77ae05.tar.xz dexon-9253fc337e4f36029f90f31b1b4e116d0a77ae05.tar.zst dexon-9253fc337e4f36029f90f31b1b4e116d0a77ae05.zip |
cmd/geth: exit the console cleanly when interrupted
This fix applies mostly to unsupported terminals that do not trigger the
special interrupt handling in liner. Supported terminals were covered
because liner.Prompt returns an error if Ctrl-C is pressed.
-rw-r--r-- | cmd/geth/js.go | 64 |
1 files changed, 44 insertions, 20 deletions
diff --git a/cmd/geth/js.go b/cmd/geth/js.go index 0fb234d45..706bc6554 100644 --- a/cmd/geth/js.go +++ b/cmd/geth/js.go @@ -22,6 +22,7 @@ import ( "fmt" "math/big" "os" + "os/signal" "path/filepath" "strings" @@ -47,7 +48,8 @@ type dumbterm struct{ r *bufio.Reader } func (r dumbterm) Prompt(p string) (string, error) { fmt.Print(p) - return r.r.ReadString('\n') + line, err := r.r.ReadString('\n') + return strings.TrimSuffix(line, "\n"), err } func (r dumbterm) PasswordPrompt(p string) (string, error) { @@ -182,30 +184,52 @@ func (self *jsre) exec(filename string) error { } func (self *jsre) interactive() { - for { - input, err := self.Prompt(self.ps1) - if err != nil { - break + // Read input lines. + prompt := make(chan string) + inputln := make(chan string) + go func() { + defer close(inputln) + for { + line, err := self.Prompt(<-prompt) + if err != nil { + return + } + inputln <- line } - if input == "" { - continue + }() + // Wait for Ctrl-C, too. + sig := make(chan os.Signal, 1) + signal.Notify(sig, os.Interrupt) + + defer func() { + if self.atexit != nil { + self.atexit() } - str += input + "\n" - self.setIndent() - if indentCount <= 0 { - if input == "exit" { - break + self.re.Stop(false) + }() + for { + prompt <- self.ps1 + select { + case <-sig: + fmt.Println("caught interrupt, exiting") + return + case input, ok := <-inputln: + if !ok || indentCount <= 0 && input == "exit" { + return + } + if input == "" { + continue + } + str += input + "\n" + self.setIndent() + if indentCount <= 0 { + hist := str[:len(str)-1] + self.AppendHistory(hist) + self.parseInput(str) + str = "" } - hist := str[:len(str)-1] - self.AppendHistory(hist) - self.parseInput(str) - str = "" } } - if self.atexit != nil { - self.atexit() - } - self.re.Stop(false) } func (self *jsre) withHistory(op func(*os.File)) { |