}
data := buf[:n]
for len(data) > 0 {
- dirent := (*syscall.Dirent)(unsafe.Pointer(&data[0]))
+ // syscall.Getdirentries's return value may be (and usually is) much
+ // smaller than a syscall.Dirent, which has lots of padding for
+ // the name at the end. The compiler's checkptr validation doesn't like
+ // that. So allocate direntMem that's always big enough, and use that
+ // when converting to *syscall.Dirent.
+ var direntMem [unsafe.Sizeof(syscall.Dirent{})]byte
+ copy(direntMem[:], data)
+ dirent := (*syscall.Dirent)(unsafe.Pointer(&direntMem[0]))
+
data = data[dirent.Reclen:]
name := make([]byte, dirent.Namlen)
for i := 0; i < int(dirent.Namlen); i++ {