From 90f55469e55eb7c882be5a01f82f539decf1dd16 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Thu, 26 Aug 2021 13:53:15 +0200 Subject: [PATCH] cmd/geth, console: better handle local console interrupt --- cmd/geth/consolecmd.go | 11 +++++++++-- console/console.go | 7 +++++-- console/console_test.go | 2 +- internal/jsre/jsre.go | 2 +- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/cmd/geth/consolecmd.go b/cmd/geth/consolecmd.go index cfd2626e7c2e..1f5d88007cdb 100644 --- a/cmd/geth/consolecmd.go +++ b/cmd/geth/consolecmd.go @@ -96,6 +96,13 @@ func localConsole(ctx *cli.Context) error { if err != nil { utils.Fatalf("Failed to start the JavaScript console: %v", err) } + exitCh := make(chan struct{}) + go func() { + // In case the blockchain is stopped, e.g. via ctrl-c, we should + // also close down the console. + stack.Wait() + close(exitCh) + }() defer console.Stop(false) // If only a short execution was requested, evaluate and return @@ -105,7 +112,7 @@ func localConsole(ctx *cli.Context) error { } // Otherwise print the welcome screen and enter interactive mode console.Welcome() - console.Interactive() + console.Interactive(exitCh) return nil } @@ -164,7 +171,7 @@ func remoteConsole(ctx *cli.Context) error { // Otherwise print the welcome screen and enter interactive mode console.Welcome() - console.Interactive() + console.Interactive(nil) return nil } diff --git a/console/console.go b/console/console.go index c1af3af12392..fa94dd539ef9 100644 --- a/console/console.go +++ b/console/console.go @@ -353,7 +353,7 @@ func (c *Console) Evaluate(statement string, abortCh chan os.Signal) { // Interactive starts an interactive user session, where input is propted from // the configured user prompter. -func (c *Console) Interactive() { +func (c *Console) Interactive(exitCh chan struct{}) { var ( prompt = c.prompt // the current prompt line (used for multi-line inputs) indents = 0 // the current number of input indents (used for multi-line inputs) @@ -380,7 +380,10 @@ func (c *Console) Interactive() { requestLine <- prompt select { - case <-interrupt: + case <-exitCh: // Exit via external notification (backend closed) + fmt.Fprintln(c.printer, "exiting console") + return + case <-interrupt: // Exit via our own os.Signal interrupt fmt.Fprintln(c.printer, "caught interrupt, exiting") return diff --git a/console/console_test.go b/console/console_test.go index 0ac37dc9d698..d7fbe51b4cac 100644 --- a/console/console_test.go +++ b/console/console_test.go @@ -202,7 +202,7 @@ func TestInteractive(t *testing.T) { tester := newTester(t, nil) defer tester.Close(t) - go tester.console.Interactive() + go tester.console.Interactive(nil) // Wait for a prompt and send a statement back select { diff --git a/internal/jsre/jsre.go b/internal/jsre/jsre.go index 89d0316d26b2..5775bf1ac5df 100644 --- a/internal/jsre/jsre.go +++ b/internal/jsre/jsre.go @@ -282,7 +282,7 @@ func (re *JSRE) Evaluate(code string, w io.Writer) { }) } -func (re *JSRE) Interrupt(v interface{}){ +func (re *JSRE) Interrupt(v interface{}) { re.vm.Interrupt(v) }