Open slingamn opened 1 year ago
I'm using the following test case with readline v1.5.1, go version go1.20 linux/amd64:
go version go1.20 linux/amd64
package main import ( "fmt" "log" "os" "strings" "time" "github.com/chzyer/readline" ) func main() { log.SetFlags(log.LstdFlags | log.Lmicroseconds) rl, err := readline.New("> ") if err != nil { log.Fatal(err) } defer rl.Close() log.SetOutput(rl.Stderr()) input := make(chan string) go func() { closed := false for { line, err := rl.Readline() if err != nil { fmt.Fprintln(os.Stderr, "error: failed to read new input line:", err.Error()) return } if !closed { input <- line } if !closed && strings.ToLower(strings.TrimSpace(line)) == "quit" { log.Printf("quit received\n") closed = true close(input) } } }() for { line, ok := <- input if !ok { log.Printf("quit acknowledged, sleeping") time.Sleep(time.Second) log.Printf("done sleeping, exiting") return } fmt.Fprintf(rl, "received %s\n", strings.TrimRight(line, "\r\n")) } }
If I enter quit at the prompt and wait, I get the following output:
quit
> quit received quit 2023/02/06 01:19:18.052671 quit received > 2023/02/06 01:19:18.053079 quit acknowledged, sleeping 2023/02/06 01:19:19.053285 done sleeping, exiting
but then the program hangs without exiting. SIGQUIT shows that the main goroutine is blocked in (*Instance).Close():
(*Instance).Close()
https://gist.github.com/slingamn/eb5bea5e623e848cd0903c29b155a0b3
It seems that this Wait() call:
Wait()
https://github.com/chzyer/readline/blob/7f93d88cd5ffa0e805d58d2f9fc3191be15ec668/terminal.go#L228
is blocked by the failure of this select to terminate:
select
https://github.com/chzyer/readline/blob/7f93d88cd5ffa0e805d58d2f9fc3191be15ec668/std.go#L120-L125
My diagnosis is that FillableStdin fails to pass the Close() call through to CancelableStdin, which would stop the select. This patch fixes the issue, but may introduce other issues:
FillableStdin
Close()
CancelableStdin
https://github.com/slingamn/readline/commit/4c5bb20c9ea7da126b421c8394fbd4cb5d4d59df
Thanks very much for your time.
I'm using the following test case with readline v1.5.1,
go version go1.20 linux/amd64
:If I enter
quit
at the prompt and wait, I get the following output:but then the program hangs without exiting. SIGQUIT shows that the main goroutine is blocked in
(*Instance).Close()
:https://gist.github.com/slingamn/eb5bea5e623e848cd0903c29b155a0b3
It seems that this
Wait()
call:https://github.com/chzyer/readline/blob/7f93d88cd5ffa0e805d58d2f9fc3191be15ec668/terminal.go#L228
is blocked by the failure of this
select
to terminate:https://github.com/chzyer/readline/blob/7f93d88cd5ffa0e805d58d2f9fc3191be15ec668/std.go#L120-L125
My diagnosis is that
FillableStdin
fails to pass theClose()
call through toCancelableStdin
, which would stop the select. This patch fixes the issue, but may introduce other issues:https://github.com/slingamn/readline/commit/4c5bb20c9ea7da126b421c8394fbd4cb5d4d59df
Thanks very much for your time.