mirror of
https://github.com/golang/go
synced 2024-09-29 04:14:27 -06:00
syscall: in TestDirent, make as many ReadDirent calls as are needed
ReadDirent returns only as many directory entries as will fit in the buffer, and each entry is variable-length — so we have no guarantee in general that a buffer of a given arbitrary size can hold even one entry, let alone all ten entries expected by the test. Instead, iterate calls to ReadDirent until one of the calls returns zero entries and no error, indicating that the directory has been read to completion. Fixes #37323 Change-Id: I7f1cedde7666107256604e4ea1ac13c71f22151a Reviewed-on: https://go-review.googlesource.com/c/go/+/376334 Trust: Bryan Mills <bcmills@google.com> Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Bryan Mills <bcmills@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
f1596d76f4
commit
be26ca972d
@ -22,7 +22,7 @@ import (
|
||||
|
||||
func TestDirent(t *testing.T) {
|
||||
const (
|
||||
direntBufSize = 2048
|
||||
direntBufSize = 2048 // arbitrary? See https://go.dev/issue/37323.
|
||||
filenameMinSize = 11
|
||||
)
|
||||
|
||||
@ -37,23 +37,38 @@ func TestDirent(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
buf := bytes.Repeat([]byte("DEADBEAF"), direntBufSize/8)
|
||||
names := make([]string, 0, 10)
|
||||
|
||||
fd, err := syscall.Open(d, syscall.O_RDONLY, 0)
|
||||
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)
|
||||
}
|
||||
buf = buf[:n]
|
||||
|
||||
names := make([]string, 0, 10)
|
||||
for len(buf) > 0 {
|
||||
var bc int
|
||||
bc, _, names = syscall.ParseDirent(buf, -1, names)
|
||||
buf = buf[bc:]
|
||||
buf := bytes.Repeat([]byte{0xCD}, direntBufSize)
|
||||
for {
|
||||
n, err := syscall.ReadDirent(fd, buf)
|
||||
if err == syscall.EINVAL {
|
||||
// On linux, 'man getdents64' says that EINVAL indicates “result buffer is too small”.
|
||||
// Try a bigger buffer.
|
||||
t.Logf("ReadDirent: %v; retrying with larger buffer", err)
|
||||
buf = bytes.Repeat([]byte{0xCD}, len(buf)*2)
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("syscall.readdir: %v", err)
|
||||
}
|
||||
t.Logf("ReadDirent: read %d bytes", n)
|
||||
if n == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
var consumed, count int
|
||||
consumed, count, names = syscall.ParseDirent(buf[:n], -1, names)
|
||||
t.Logf("ParseDirent: %d new name(s)", count)
|
||||
if consumed != n {
|
||||
t.Fatalf("ParseDirent: consumed %d bytes; expected %d", consumed, n)
|
||||
}
|
||||
}
|
||||
|
||||
sort.Strings(names)
|
||||
|
Loading…
Reference in New Issue
Block a user