os: File.Seek() not resetting directory reads on MacOS Catalina
caseybarker opened this issue · 5 comments
What version of Go are you using (go version)?
$ go version go version go1.13.4 darwin/amd64
Does this issue reproduce with the latest release?
This is the latest.
What operating system and processor architecture are you using (go env)?
go env Output
$ go env GO111MODULE="" GOARCH="amd64" GOBIN="" GOCACHE="/Users/cbarkerj/Library/Caches/go-build" GOENV="/Users/cbarkerj/Library/Application Support/go/env" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="darwin" GONOPROXY="" GONOSUMDB="" GOOS="darwin" GOPATH="/Users/cbarkerj/go" GOPRIVATE="" GOPROXY="https://proxy.golang.org,direct" GOROOT="/usr/local/go" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64" GCCGO="gccgo" AR="ar" CC="clang" CXX="clang++" CGO_ENABLED="1" GOMOD="" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/9_/kzjd637s5n153w9g3zqc1hmh0000gn/T/go-build108700530=/tmp/go-build -gno-record-gcc-switches -fno-common"
What did you do?
This piece of code opens a directory file and calls f.Readdirnames(0). Then it calls f.Seek(0, 0) to reset to the head of the file, and calls f.Readdirnames(0) again.
https://play.golang.org/p/IEb3BH2Jlxg
What did you expect to see?
On Linux, the playground, and earlier versions of MacOS, the second call to f.Readdirnames(0) returns the same directory list as the first call:
$ go build .
$ ./test
2019/11/21 16:56:37 try 1:[test main.go]
2019/11/21 16:56:37 seeked to offset: 0
2019/11/21 16:56:37 try 2:[test main.go]
What did you see instead?
On MacOS 10.15.1 Catalina, the second call returns an empty list:
% go build .
% ./test
2019/11/21 16:55:22 try 1:[test main.go]
2019/11/21 16:55:22 seeked to offset: 0
2019/11/21 16:55:22 try 2:[]
cc @odeke-em @eliasnaur @ianlancetaylor
@gopherbot add OS-Darwin
I guess this is not a 1.14 release blocker since it is broken in 1.13, but it would be nice to fix.
CC @randall77
Out of curiosity, I tested File.Seek() for regular file reads. That works as expected.
I think the problem here is that the first Readdirnames calls opendir and caches the result. The behavior of that cached opendir result isn't specified on a seek of the underlying fd:
Upon successful return from fdopendir(), the file descriptor is under the control of the system, and if any attempt is made to close the file descriptor, or to modify the state of the associated description other than by means of closedir(), readdir(), readdir_r(), or rewinddir(), the behavior is undefined.
Seek should really invalidate any outstanding opendir result.
I'll hack up a patch.
Change https://golang.org/cl/209961 mentions this issue: os: reset dirinfo when seeking on Darwin