mattn / go-tty

MIT License
208 stars 18 forks source link

How to cancel a Read #44

Open AnomalRoil opened 2 years ago

AnomalRoil commented 2 years ago

I'm using the following example:

tty, err := tty.Open()
if err != nil {
    log.Fatal(err)
}
defer tty.Close()

for {
    r, err := tty.ReadRune()
    if err != nil {
        log.Fatal(err)
    }
    // handle key event
}

which is running in a Go routine, but sadly there are cases where I don't need to wait for user input anymore (e.g. a timer elapsed) and so would love to be able to cancel the ReadRune call, since it seems to be blocking. If I cannot cancel the Read, I have a dangling, leaked Go routine running in the background, which is annoying on a system that is running for a long time.

I've tried doing:

tty.Input().Close()

to close the underlying os.File, hoping it would cancel the Read, but it doesn't.

I also started looking into https://pkg.go.dev/os#File.SetReadDeadline but since it seems that the os.Open("/dev/tty") is not recognized as a type on which we can set a Deadline as it errors out with "file type does not support deadline".

So here am I: how can I cancel a ReadRune in a Go routine while it is waiting for user input ?

ZenLiuCN commented 1 year ago
go func(ch chan rune){ 
for{
    r, err := tty.ReadRune()
    if err != nil {
        return
    }
ch <-r
}}(ch)
//handle
for c:=range ch{
//handle
}
//timeout 
tty.Close()
fess932 commented 2 months ago

same? https://github.com/mattn/go-tty/issues/50