const DevNull = "/dev/null"
// openFileNolog is the Unix implementation of OpenFile.
+// Changes here should be reflected in openFdAt, if relevant.
func openFileNolog(name string, flag int, perm FileMode) (*File, error) {
setSticky := false
if !supportsCreateWithStickyBit && flag&O_CREATE != 0 && perm&ModeSticky != 0 {
import (
"internal/syscall/unix"
"io"
+ "runtime"
"syscall"
)
return unlinkError
}
-func openFdAt(fd int, path string) (*File, error) {
- fd, err := unix.Openat(fd, path, O_RDONLY, 0)
- if err != nil {
- return nil, err
+// openFdAt opens path relative to the directory in fd.
+// Other than that this should act like openFileNolog.
+// This acts like openFileNolog rather than OpenFile because
+// we are going to (try to) remove the file.
+// The contents of this file are not relevant for test caching.
+func openFdAt(dirfd int, name string) (*File, error) {
+ var r int
+ for {
+ var e error
+ r, e = unix.Openat(dirfd, name, O_RDONLY, 0)
+ if e == nil {
+ break
+ }
+
+ // See comment in openFileNolog.
+ if runtime.GOOS == "darwin" && e == syscall.EINTR {
+ continue
+ }
+
+ return nil, &PathError{"openat", name, e}
+ }
+
+ if !supportsCloseOnExec {
+ syscall.CloseOnExec(r)
}
- return NewFile(uintptr(fd), path), nil
+ return newFile(uintptr(r), name, kindOpenFile), nil
}