mirror of
https://github.com/junegunn/fzf.git
synced 2026-09-18 01:33:18 +08:00
Fix spurious exit while waiting for a key with --listen
- getch() charged EINTR against a 100 iteration limit meant for read
attempts, and the count only reset once a byte was read
- So signals arriving during an idle prompt drained it, and running out
returned getCharError, which became Event{Fatal} and exit status 2
- Only the cancellable path is affected, hence only --listen
- select() is not restarted by SA_RESTART, unlike the blocking read on
the non-cancellable path, so it is the only one that sees EINTR
- waitReadable() already retries EINTR without a limit
Fix #4917
This commit is contained in:
@@ -27,7 +27,6 @@ const (
|
||||
queryTimeout = 500 * time.Millisecond
|
||||
maxInputBuffer = 1024 * 1024
|
||||
escapeLookback = 256
|
||||
maxSelectTries = 100
|
||||
)
|
||||
|
||||
const DefaultTtyDevice string = "/dev/tty"
|
||||
|
||||
@@ -240,7 +240,7 @@ func (r *LightRenderer) getch(cancellable bool, nonblock bool) (int, getCharResu
|
||||
}()
|
||||
|
||||
cancelFd := int(rpipe.Fd())
|
||||
for range maxSelectTries {
|
||||
for {
|
||||
var rfds unix.FdSet
|
||||
limit := len(rfds.Bits) * unix.NFDBITS
|
||||
if fd >= limit || cancelFd >= limit {
|
||||
@@ -251,6 +251,8 @@ func (r *LightRenderer) getch(cancellable bool, nonblock bool) (int, getCharResu
|
||||
rfds.Set(cancelFd)
|
||||
_, err := unix.Select(max(fd, cancelFd)+1, &rfds, nil, nil, nil)
|
||||
if err != nil {
|
||||
// An interrupted wait is not a failed read, so it must not count
|
||||
// against anything. Retry until the fd is ready or the wait fails.
|
||||
if err == syscall.EINTR {
|
||||
continue
|
||||
}
|
||||
@@ -265,7 +267,6 @@ func (r *LightRenderer) getch(cancellable bool, nonblock bool) (int, getCharResu
|
||||
return getter()
|
||||
}
|
||||
}
|
||||
return 0, getCharError
|
||||
}
|
||||
|
||||
func (r *LightRenderer) Size() TermSize {
|
||||
|
||||
Reference in New Issue
Block a user