diff --git a/internal/fastwalk/fastwalk_dirent_namlen_bsd.go b/internal/fastwalk/fastwalk_dirent_namlen_bsd.go new file mode 100644 index 0000000000..a3b26a7bae --- /dev/null +++ b/internal/fastwalk/fastwalk_dirent_namlen_bsd.go @@ -0,0 +1,13 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin freebsd openbsd netbsd + +package fastwalk + +import "syscall" + +func direntNamlen(dirent *syscall.Dirent) uint64 { + return uint64(dirent.Namlen) +} diff --git a/internal/fastwalk/fastwalk_dirent_namlen_linux.go b/internal/fastwalk/fastwalk_dirent_namlen_linux.go new file mode 100644 index 0000000000..61896ffe7e --- /dev/null +++ b/internal/fastwalk/fastwalk_dirent_namlen_linux.go @@ -0,0 +1,24 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build linux +// +build !appengine + +package fastwalk + +import ( + "bytes" + "syscall" + "unsafe" +) + +func direntNamlen(dirent *syscall.Dirent) uint64 { + const fixedHdr = uint16(unsafe.Offsetof(syscall.Dirent{}.Name)) + nameBuf := (*[unsafe.Sizeof(dirent.Name)]byte)(unsafe.Pointer(&dirent.Name[0])) + nameLen := bytes.IndexByte(nameBuf[:dirent.Reclen-fixedHdr], 0) + if nameLen < 0 { + panic("failed to find terminating 0 byte in dirent") + } + return uint64(nameLen) +} diff --git a/internal/fastwalk/fastwalk_unix.go b/internal/fastwalk/fastwalk_unix.go index e541c57506..3369b1a0b2 100644 --- a/internal/fastwalk/fastwalk_unix.go +++ b/internal/fastwalk/fastwalk_unix.go @@ -8,7 +8,6 @@ package fastwalk import ( - "bytes" "fmt" "os" "syscall" @@ -114,10 +113,7 @@ func parseDirEnt(buf []byte) (consumed int, name string, typ os.FileMode) { } nameBuf := (*[unsafe.Sizeof(dirent.Name)]byte)(unsafe.Pointer(&dirent.Name[0])) - nameLen := bytes.IndexByte(nameBuf[:], 0) - if nameLen < 0 { - panic("failed to find terminating 0 byte in dirent") - } + nameLen := direntNamlen(dirent) // Special cases for common things: if nameLen == 1 && nameBuf[0] == '.' {