aboutsummaryrefslogtreecommitdiff
path: root/internal/fastwalk
diff options
context:
space:
mode:
authorIchinose Shogo <shogo82148@gmail.com>2021-02-22 01:30:12 +0900
committerHeschi Kreinick <heschi@google.com>2021-02-24 01:32:32 +0000
commit0150491f5f0a1af95c6e9215e405c6200090bbeb (patch)
treeb524f18463dfb8ba74a09c760b4bbed737ca9b49 /internal/fastwalk
parentb4639ccb830b1c9602f1c96eba624bbbe20650ea (diff)
downloadgolang-x-tools-0150491f5f0a1af95c6e9215e405c6200090bbeb.tar.gz
x/tools/internal/fastwalk: fixes "interrupted system call" error
According to https://golang.org/doc/go1.14#runtime A consequence of the implementation of preemption is that on Unix systems, including Linux and macOS systems, programs built with Go 1.14 will receive more signals than programs built with earlier releases. This causes syscall.Open and syscall.ReadDirent sometimes fail with EINTR errors. We need to retry in this case. Fixes golang/go#44478 Change-Id: I0b0291471e47e8682fac791e1ed024b5a42a56f8 Reviewed-on: https://go-review.googlesource.com/c/tools/+/294730 Reviewed-by: Heschi Kreinick <heschi@google.com> Trust: Heschi Kreinick <heschi@google.com> Trust: Peter Weinberger <pjw@google.com> Run-TryBot: Heschi Kreinick <heschi@google.com> gopls-CI: kokoro <noreply+kokoro@google.com> TryBot-Result: Go Bot <gobot@golang.org>
Diffstat (limited to 'internal/fastwalk')
-rw-r--r--internal/fastwalk/fastwalk_unix.go28
1 files changed, 26 insertions, 2 deletions
diff --git a/internal/fastwalk/fastwalk_unix.go b/internal/fastwalk/fastwalk_unix.go
index e4edb5cde..58bd87841 100644
--- a/internal/fastwalk/fastwalk_unix.go
+++ b/internal/fastwalk/fastwalk_unix.go
@@ -22,7 +22,7 @@ const blockSize = 8 << 10
const unknownFileMode os.FileMode = os.ModeNamedPipe | os.ModeSocket | os.ModeDevice
func readDir(dirName string, fn func(dirName, entName string, typ os.FileMode) error) error {
- fd, err := syscall.Open(dirName, 0, 0)
+ fd, err := open(dirName, 0, 0)
if err != nil {
return &os.PathError{Op: "open", Path: dirName, Err: err}
}
@@ -36,7 +36,7 @@ func readDir(dirName string, fn func(dirName, entName string, typ os.FileMode) e
for {
if bufp >= nbuf {
bufp = 0
- nbuf, err = syscall.ReadDirent(fd, buf)
+ nbuf, err = readDirent(fd, buf)
if err != nil {
return os.NewSyscallError("readdirent", err)
}
@@ -127,3 +127,27 @@ func parseDirEnt(buf []byte) (consumed int, name string, typ os.FileMode) {
}
return
}
+
+// According to https://golang.org/doc/go1.14#runtime
+// A consequence of the implementation of preemption is that on Unix systems, including Linux and macOS
+// systems, programs built with Go 1.14 will receive more signals than programs built with earlier releases.
+//
+// This causes syscall.Open and syscall.ReadDirent sometimes fail with EINTR errors.
+// We need to retry in this case.
+func open(path string, mode int, perm uint32) (fd int, err error) {
+ for {
+ fd, err := syscall.Open(path, mode, perm)
+ if err != syscall.EINTR {
+ return fd, err
+ }
+ }
+}
+
+func readDirent(fd int, buf []byte) (n int, err error) {
+ for {
+ nbuf, err := syscall.ReadDirent(fd, buf)
+ if err != syscall.EINTR {
+ return nbuf, err
+ }
+ }
+}