diff options
Diffstat (limited to 'libgo/go/syscall/dirent_bsd_test.go')
-rw-r--r-- | libgo/go/syscall/dirent_bsd_test.go | 71 |
1 files changed, 69 insertions, 2 deletions
diff --git a/libgo/go/syscall/dirent_bsd_test.go b/libgo/go/syscall/dirent_bsd_test.go index e5f5eb3..43b667b 100644 --- a/libgo/go/syscall/dirent_bsd_test.go +++ b/libgo/go/syscall/dirent_bsd_test.go @@ -2,20 +2,23 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin,!arm,!arm64 dragonfly freebsd netbsd openbsd +// +build darwin dragonfly freebsd netbsd openbsd package syscall_test import ( "bytes" + "fmt" "io/ioutil" "os" "path/filepath" + "runtime" "sort" "strconv" "strings" "syscall" "testing" + "unsafe" ) func TestDirent(t *testing.T) { @@ -41,10 +44,10 @@ func TestDirent(t *testing.T) { buf := bytes.Repeat([]byte("DEADBEAF"), direntBufSize/8) fd, err := syscall.Open(d, syscall.O_RDONLY, 0) - defer syscall.Close(fd) if err != nil { t.Fatalf("syscall.open: %v", err) } + defer syscall.Close(fd) n, err := syscall.ReadDirent(fd, buf) if err != nil { t.Fatalf("syscall.readdir: %v", err) @@ -74,3 +77,67 @@ func TestDirent(t *testing.T) { } } } + +func TestDirentRepeat(t *testing.T) { + const N = 100 + // Note: the size of the buffer is small enough that the loop + // below will need to execute multiple times. See issue #31368. + size := N * unsafe.Offsetof(syscall.Dirent{}.Name) / 4 + if runtime.GOOS == "freebsd" || runtime.GOOS == "netbsd" { + if size < 1024 { + size = 1024 // DIRBLKSIZ, see issue 31403. + } + if runtime.GOOS == "freebsd" { + t.Skip("need to fix issue 31416 first") + } + } + + // Make a directory containing N files + d, err := ioutil.TempDir("", "direntRepeat-test") + if err != nil { + t.Fatalf("tempdir: %v", err) + } + defer os.RemoveAll(d) + + var files []string + for i := 0; i < N; i++ { + files = append(files, fmt.Sprintf("file%d", i)) + } + for _, file := range files { + err = ioutil.WriteFile(filepath.Join(d, file), []byte("contents"), 0644) + if err != nil { + t.Fatalf("writefile: %v", err) + } + } + + // Read the directory entries using ReadDirent. + fd, err := syscall.Open(d, syscall.O_RDONLY, 0) + if err != nil { + t.Fatalf("syscall.open: %v", err) + } + defer syscall.Close(fd) + var files2 []string + for { + buf := make([]byte, size) + n, err := syscall.ReadDirent(fd, buf) + if err != nil { + t.Fatalf("syscall.readdir: %v", err) + } + if n == 0 { + break + } + buf = buf[:n] + for len(buf) > 0 { + var consumed int + consumed, _, files2 = syscall.ParseDirent(buf, -1, files2) + buf = buf[consumed:] + } + } + + // Check results + sort.Strings(files) + sort.Strings(files2) + if strings.Join(files, "|") != strings.Join(files2, "|") { + t.Errorf("bad file list: want\n%q\ngot\n%q", files, files2) + } +} |