From 6d0305dc7d6557c008f0b5cdd4df013ba7b3d6a8 Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Tue, 16 Sep 2014 10:39:57 -0700 Subject: [PATCH] go.sys/unix: undo CL 119530044's effects in go.sys for BSD That CL worked around a bug present in the OS X Yosemite Public Beta versions 1 and 2. Beta 3 (released today) has fixed the bug. LGTM=bradfitz R=golang-codereviews, bradfitz CC=golang-codereviews https://golang.org/cl/144010043 --- unix/syscall_bsd.go | 35 +---------------------------------- 1 file changed, 1 insertion(+), 34 deletions(-) diff --git a/unix/syscall_bsd.go b/unix/syscall_bsd.go index 97de3459..7b08113b 100644 --- a/unix/syscall_bsd.go +++ b/unix/syscall_bsd.go @@ -69,40 +69,7 @@ func ReadDirent(fd int, buf []byte) (n int, err error) { // actual system call is getdirentries64, 64 is a good guess. // TODO(rsc): Can we use a single global basep for all calls? var base = (*uintptr)(unsafe.Pointer(new(uint64))) - n, err = Getdirentries(fd, buf, base) - - // On OS X 10.10 Yosemite, if you have a directory that can be returned - // in a single getdirentries64 call (for example, a directory with one file), - // and you read from the directory at EOF twice, you get EOF both times: - // fd = open("dir") - // getdirentries64(fd) // returns data - // getdirentries64(fd) // returns 0 (EOF) - // getdirentries64(fd) // returns 0 (EOF) - // - // But if you remove the file in the middle between the two calls, the - // second call returns an error instead. - // fd = open("dir") - // getdirentries64(fd) // returns data - // getdirentries64(fd) // returns 0 (EOF) - // remove("dir/file") - // getdirentries64(fd) // returns ENOENT/EINVAL - // - // Whether you get ENOENT or EINVAL depends on exactly what was - // in the directory. It is deterministic, just data-dependent. - // - // This only happens in small directories. A directory containing more data - // than fits in a 4k getdirentries64 call will return EOF correctly. - // (It's not clear if the criteria is that the directory be split across multiple - // getdirentries64 calls or that it be split across multiple file system blocks.) - // - // We could change package os to avoid the second read at EOF, - // and maybe we should, but that's a bit involved. - // For now, treat the EINVAL/ENOENT as EOF. - if runtime.GOOS == "darwin" && (err == EINVAL || err == ENOENT) { - err = nil - } - - return + return Getdirentries(fd, buf, base) } // Wait status is 7 bits at bottom, either 0 (exited),