aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Lange <fjl@twurst.com>2015-05-27 06:52:02 +0800
committerFelix Lange <fjl@twurst.com>2015-05-27 06:54:48 +0800
commit9253fc337e4f36029f90f31b1b4e116d0a77ae05 (patch)
treea45d322eb3ec37a1b278370ce0eecb8e4aaad275
parent612f01400f59b0b4d0db9f9ceaa38f45805ea89e (diff)
downloaddexon-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.go64
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)) {