1 // Copyright 2019 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // +build darwin freebsd netbsd openbsd
21 func TestGetdirentries(t
*testing
.T
) {
22 for _
, count
:= range []int{10, 1000} {
23 t
.Run(fmt
.Sprintf("n=%d", count
), func(t
*testing
.T
) {
24 testGetdirentries(t
, count
)
28 func testGetdirentries(t
*testing
.T
, count
int) {
29 if count
> 100 && testing
.Short() && os
.Getenv("GO_BUILDER_NAME") == "" {
30 t
.Skip("skipping in -short mode")
32 d
, err
:= ioutil
.TempDir("", "getdirentries-test")
34 t
.Fatalf("Tempdir: %v", err
)
38 for i
:= 0; i
< count
; i
++ {
39 names
= append(names
, fmt
.Sprintf("file%03d", i
))
42 // Make files in the temp directory
43 for _
, name
:= range names
{
44 err
:= ioutil
.WriteFile(filepath
.Join(d
, name
), []byte("data"), 0)
46 t
.Fatalf("WriteFile: %v", err
)
50 // Read files using Getdirentries
52 fd
, err
:= syscall
.Open(d
, syscall
.O_RDONLY
, 0)
54 t
.Fatalf("Open: %v", err
)
56 defer syscall
.Close(fd
)
60 n
, err
:= syscall
.Getdirentries(fd
, buf
[:], &base
)
62 t
.Fatalf("Getdirentries: %v", err
)
69 // If multiple Dirents are written into buf, sometimes when we reach the final one,
70 // we have cap(buf) < Sizeof(Dirent). So use an appropriate slice to copy from data.
71 var dirent syscall
.Dirent
72 copy((*[unsafe
.Sizeof(dirent
)]byte)(unsafe
.Pointer(&dirent
))[:], data
)
74 data
= data
[dirent
.Reclen
:]
75 name
:= make([]byte, dirent
.Namlen
)
76 for i
:= 0; i
< int(dirent
.Namlen
); i
++ {
77 name
[i
] = byte(dirent
.Name
[i
])
79 names2
= append(names2
, string(name
))
83 names
= append(names
, ".", "..") // Getdirentries returns these also
86 if strings
.Join(names
, ":") != strings
.Join(names2
, ":") {
87 t
.Errorf("names don't match\n names: %q\nnames2: %q", names
, names2
)