Skip to content

Commit

Permalink
os: handle EINTR from open(2).
Browse files Browse the repository at this point in the history
The man page for sigaction(2) on OS X 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 #11180.

Change-Id: I967247430e20a7d29a285b3d76bf3498dc4773db
Reviewed-on: https://go-review.googlesource.com/14484
Reviewed-by: Ian Lance Taylor <[email protected]>
TryBot-Result: Gobot Gobot <[email protected]>
  • Loading branch information
jacobsa authored and ianlancetaylor committed Sep 17, 2015
1 parent 9337dc9 commit 50d0ee0
Showing 1 changed file with 8 additions and 0 deletions.
8 changes: 8 additions & 0 deletions 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 {
// 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).
if e == syscall.EINTR {
goto retry
}

return nil, &PathError{"open", name, e}
}

Expand Down

0 comments on commit 50d0ee0

Please sign in to comment.