Skip to content

Commit a4fb629

Browse files
committed
os: handle EINTR from open(2) on darwin.
The man page for sigaction(2) doesn't guarantee that SA_RESTART will work for open(2) on regular files: The affected system calls include open(2), read(2), write(2), sendto(2), recvfrom(2), sendmsg(2) and recvmsg(2) on a communications channel or a slow device (such as a terminal, but not a regular file) and during a wait(2) or ioctl(2). I've never observed EINTR from open(2) for a traditional file system such as HFS+, but it's easy to observe with a fuse file system that is slightly slow (cf. https://goo.gl/UxsVgB). After this change, the problem can no longer be reproduced when calling os.OpenFile. Fixes golang#11180. Change-Id: I967247430e20a7d29a285b3d76bf3498dc4773db
1 parent 3f2baa3 commit a4fb629

File tree

1 file changed

+9
-1
lines changed

1 file changed

+9
-1
lines changed

src/os/file_unix.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,16 @@ func OpenFile(name string, flag int, perm FileMode) (*File, error) {
9090
}
9191
}
9292

93+
retry:
9394
r, e := syscall.Open(name, flag|syscall.O_CLOEXEC, syscallMode(perm))
94-
if e != nil {
95+
switch {
96+
// On OS X, sigaction(2) doesn't guarantee that SA_RESTART will cause open(2)
97+
// to be restarted for regular files. This is easy to reproduce on fuse file
98+
// systems (see http://golang.org/issue/11180).
99+
case runtime.GOOS == "darwin" && e == syscall.EINTR:
100+
goto retry
101+
102+
case e != nil:
95103
return nil, &PathError{"open", name, e}
96104
}
97105

0 commit comments

Comments
 (0)