Skip to content

Commit ae220b9

Browse files
justenwalkermuesli
authored andcommitted
fix: retry sysSelect in Darwin on EINTR
In certain situations, the read of the terminal fd will fail, returning an EINTR on Darwin. This causes the status report to be printed to stdout, since the read never occurs. Similar to issue golang/go#22838 Fixes: #12
1 parent 7d11330 commit ae220b9

File tree

1 file changed

+15
-6
lines changed

1 file changed

+15
-6
lines changed

termenv_unix.go

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package termenv
44

55
import (
66
"os"
7+
"runtime"
78
"strconv"
89
"strings"
910
"syscall"
@@ -75,15 +76,23 @@ func readWithTimeout(f *os.File) (string, bool) {
7576
fd := f.Fd()
7677
readfds.Bits[fd/64] |= 1 << (fd % 64)
7778

78-
// Use select to attempt to read from os.Stdout for 100 ms
79-
err := sysSelect(int(fd)+1,
80-
&readfds,
81-
&syscall.Timeval{Usec: 100000})
82-
83-
if err != nil {
79+
for {
80+
// Use select to attempt to read from os.Stdout for 100 ms
81+
err := sysSelect(int(fd)+1,
82+
&readfds,
83+
&syscall.Timeval{Usec: 100000})
84+
if err == nil {
85+
break
86+
}
87+
// On MacOS we can see EINTR here if the user
88+
// pressed ^Z. Similar to issue https://github.com/golang/go/issues/22838
89+
if runtime.GOOS == "darwin" && err == syscall.EINTR {
90+
continue
91+
}
8492
// log.Printf("select(read error): %v", err)
8593
return "", false
8694
}
95+
8796
if readfds.Bits[fd/64]&(1<<(fd%64)) == 0 {
8897
// log.Print("select(read timeout)")
8998
return "", false

0 commit comments

Comments
 (0)