}
}
+// Readdir on a regular file should fail.
+func TestReaddirOfFile(t *testing.T) {
+ f, err := ioutil.TempFile("", "_Go_ReaddirOfFile")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer Remove(f.Name())
+ f.Write([]byte("foo"))
+ f.Close()
+ reg, err := Open(f.Name())
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer reg.Close()
+
+ names, err := reg.Readdirnames(-1)
+ if err == nil {
+ t.Error("Readdirnames succeeded; want non-nil error")
+ }
+ if len(names) > 0 {
+ t.Errorf("unexpected dir names in regular file: %q", names)
+ }
+}
+
func TestHardLink(t *testing.T) {
// Hardlinks are not supported under windows or Plan 9.
if runtime.GOOS == "plan9" {
// 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),