Path: blob/main/vendor/golang.org/x/sys/unix/dirent.go
2880 views
// Copyright 2009 The Go Authors. All rights reserved.1// Use of this source code is governed by a BSD-style2// license that can be found in the LICENSE file.34//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos56package unix78import "unsafe"910// readInt returns the size-bytes unsigned integer in native byte order at offset off.11func readInt(b []byte, off, size uintptr) (u uint64, ok bool) {12if len(b) < int(off+size) {13return 0, false14}15if isBigEndian {16return readIntBE(b[off:], size), true17}18return readIntLE(b[off:], size), true19}2021func readIntBE(b []byte, size uintptr) uint64 {22switch size {23case 1:24return uint64(b[0])25case 2:26_ = b[1] // bounds check hint to compiler; see golang.org/issue/1480827return uint64(b[1]) | uint64(b[0])<<828case 4:29_ = b[3] // bounds check hint to compiler; see golang.org/issue/1480830return uint64(b[3]) | uint64(b[2])<<8 | uint64(b[1])<<16 | uint64(b[0])<<2431case 8:32_ = b[7] // bounds check hint to compiler; see golang.org/issue/1480833return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |34uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<5635default:36panic("syscall: readInt with unsupported size")37}38}3940func readIntLE(b []byte, size uintptr) uint64 {41switch size {42case 1:43return uint64(b[0])44case 2:45_ = b[1] // bounds check hint to compiler; see golang.org/issue/1480846return uint64(b[0]) | uint64(b[1])<<847case 4:48_ = b[3] // bounds check hint to compiler; see golang.org/issue/1480849return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<2450case 8:51_ = b[7] // bounds check hint to compiler; see golang.org/issue/1480852return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |53uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<5654default:55panic("syscall: readInt with unsupported size")56}57}5859// ParseDirent parses up to max directory entries in buf,60// appending the names to names. It returns the number of61// bytes consumed from buf, the number of entries added62// to names, and the new names slice.63func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) {64origlen := len(buf)65count = 066for max != 0 && len(buf) > 0 {67reclen, ok := direntReclen(buf)68if !ok || reclen > uint64(len(buf)) {69return origlen, count, names70}71rec := buf[:reclen]72buf = buf[reclen:]73ino, ok := direntIno(rec)74if !ok {75break76}77if ino == 0 { // File absent in directory.78continue79}80const namoff = uint64(unsafe.Offsetof(Dirent{}.Name))81namlen, ok := direntNamlen(rec)82if !ok || namoff+namlen > uint64(len(rec)) {83break84}85name := rec[namoff : namoff+namlen]86for i, c := range name {87if c == 0 {88name = name[:i]89break90}91}92// Check for useless names before allocating a string.93if string(name) == "." || string(name) == ".." {94continue95}96max--97count++98names = append(names, string(name))99}100return origlen - len(buf), count, names101}102103104