зеркало из https://github.com/golang/tools.git
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>
This commit is contained in:
Родитель
b4639ccb83
Коммит
0150491f5f
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче