Source file
src/syscall/dirent_test.go
Documentation: syscall
1
2
3
4
5
6
7
8 package syscall_test
9
10 import (
11 "bytes"
12 "fmt"
13 "os"
14 "path/filepath"
15 "runtime"
16 "sort"
17 "strconv"
18 "strings"
19 "syscall"
20 "testing"
21 "unsafe"
22 )
23
24 func TestDirent(t *testing.T) {
25 const (
26 direntBufSize = 2048
27 filenameMinSize = 11
28 )
29
30 d := t.TempDir()
31 t.Logf("tmpdir: %s", d)
32
33 for i, c := range []byte("0123456789") {
34 name := string(bytes.Repeat([]byte{c}, filenameMinSize+i))
35 err := os.WriteFile(filepath.Join(d, name), nil, 0644)
36 if err != nil {
37 t.Fatalf("writefile: %v", err)
38 }
39 }
40
41 buf := bytes.Repeat([]byte("DEADBEAF"), direntBufSize/8)
42 fd, err := syscall.Open(d, syscall.O_RDONLY, 0)
43 if err != nil {
44 t.Fatalf("syscall.open: %v", err)
45 }
46 defer syscall.Close(fd)
47 n, err := syscall.ReadDirent(fd, buf)
48 if err != nil {
49 t.Fatalf("syscall.readdir: %v", err)
50 }
51 buf = buf[:n]
52
53 names := make([]string, 0, 10)
54 for len(buf) > 0 {
55 var bc int
56 bc, _, names = syscall.ParseDirent(buf, -1, names)
57 buf = buf[bc:]
58 }
59
60 sort.Strings(names)
61 t.Logf("names: %q", names)
62
63 if len(names) != 10 {
64 t.Errorf("got %d names; expected 10", len(names))
65 }
66 for i, name := range names {
67 ord, err := strconv.Atoi(name[:1])
68 if err != nil {
69 t.Fatalf("names[%d] is non-integer %q: %v", i, names[i], err)
70 }
71 if expected := string(strings.Repeat(name[:1], filenameMinSize+ord)); name != expected {
72 t.Errorf("names[%d] is %q (len %d); expected %q (len %d)", i, name, len(name), expected, len(expected))
73 }
74 }
75 }
76
77 func TestDirentRepeat(t *testing.T) {
78 const N = 100
79
80
81 size := N * unsafe.Offsetof(syscall.Dirent{}.Name) / 4
82 if runtime.GOOS == "freebsd" || runtime.GOOS == "netbsd" {
83 if size < 1024 {
84 size = 1024
85 }
86 if runtime.GOOS == "freebsd" {
87 t.Skip("need to fix issue 31416 first")
88 }
89 }
90
91
92 d := t.TempDir()
93
94 var files []string
95 for i := 0; i < N; i++ {
96 files = append(files, fmt.Sprintf("file%d", i))
97 }
98 for _, file := range files {
99 err := os.WriteFile(filepath.Join(d, file), []byte("contents"), 0644)
100 if err != nil {
101 t.Fatalf("writefile: %v", err)
102 }
103 }
104
105
106 fd, err := syscall.Open(d, syscall.O_RDONLY, 0)
107 if err != nil {
108 t.Fatalf("syscall.open: %v", err)
109 }
110 defer syscall.Close(fd)
111 var files2 []string
112 for {
113 buf := make([]byte, size)
114 n, err := syscall.ReadDirent(fd, buf)
115 if err != nil {
116 t.Fatalf("syscall.readdir: %v", err)
117 }
118 if n == 0 {
119 break
120 }
121 buf = buf[:n]
122 for len(buf) > 0 {
123 var consumed int
124 consumed, _, files2 = syscall.ParseDirent(buf, -1, files2)
125 buf = buf[consumed:]
126 }
127 }
128
129
130 sort.Strings(files)
131 sort.Strings(files2)
132 if strings.Join(files, "|") != strings.Join(files2, "|") {
133 t.Errorf("bad file list: want\n%q\ngot\n%q", files, files2)
134 }
135 }
136
View as plain text