Skip to content

Commit

Permalink
os: handle EINTR from open(2) on darwin.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
jacobsa committed Sep 10, 2015
1 parent 3f2baa3 commit a4fb629
Showing 1 changed file with 9 additions and 1 deletion.
10 changes: 9 additions & 1 deletion src/os/file_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,16 @@ func OpenFile(name string, flag int, perm FileMode) (*File, error) {
}
}

retry:
r, e := syscall.Open(name, flag|syscall.O_CLOEXEC, syscallMode(perm))
if e != nil {
switch {
// On OS X, sigaction(2) doesn't guarantee that SA_RESTART will cause open(2)
// to be restarted for regular files. This is easy to reproduce on fuse file
// systems (see http://golang.org/issue/11180).
case runtime.GOOS == "darwin" && e == syscall.EINTR:
goto retry

case e != nil:
return nil, &PathError{"open", name, e}
}

Expand Down

0 comments on commit a4fb629

Please sign in to comment.