// Copyright 2009 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. //go:build unix || (js && wasm) || wasip1 package syscall import ( "internal/byteorder" "internal/goarch" "runtime" "unsafe" ) // readInt returns the size-bytes unsigned integer in native byte order at offset off. func readInt(b []byte, off, size uintptr) (u uint64, ok bool) { if len(b) < int(off+size) { return 0, false } if goarch.BigEndian { return readIntBE(b[off:], size), true } return readIntLE(b[off:], size), true } func readIntBE(b []byte, size uintptr) uint64 { switch size { case 1: return uint64(b[0]) case 2: return uint64(byteorder.BeUint16(b)) case 4: return uint64(byteorder.BeUint32(b)) case 8: return uint64(byteorder.BeUint64(b)) default: panic("syscall: readInt with unsupported size") } } func readIntLE(b []byte, size uintptr) uint64 { switch size { case 1: return uint64(b[0]) case 2: return uint64(byteorder.LeUint16(b)) case 4: return uint64(byteorder.LeUint32(b)) case 8: return uint64(byteorder.LeUint64(b)) default: panic("syscall: readInt with unsupported size") } } // ParseDirent parses up to max directory entries in buf, // appending the names to names. It returns the number of // bytes consumed from buf, the number of entries added // to names, and the new names slice. func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) { origlen := len(buf) count = 0 for max != 0 && len(buf) > 0 { reclen, ok := direntReclen(buf) if !ok || reclen > uint64(len(buf)) { return origlen, count, names } rec := buf[:reclen] buf = buf[reclen:] ino, ok := direntIno(rec) if !ok { break } // See src/os/dir_unix.go for the reason why this condition is // excluded on wasip1. if ino == 0 && runtime.GOOS != "wasip1" { // File absent in directory. continue } const namoff = uint64(unsafe.Offsetof(Dirent{}.Name)) namlen, ok := direntNamlen(rec) if !ok || namoff+namlen > uint64(len(rec)) { break } name := rec[namoff : namoff+namlen] for i, c := range name { if c == 0 { name = name[:i] break } } // Check for useless names before allocating a string. if string(name) == "." || string(name) == ".." { continue } max-- count++ names = append(names, string(name)) } return origlen - len(buf), count, names }