1// Copyright 2020 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package os
6
7import (
8	"syscall"
9	"unsafe"
10)
11
12func direntIno(buf []byte) (uint64, bool) {
13	return readInt(buf, unsafe.Offsetof(syscall.Dirent{}.Fileno), unsafe.Sizeof(syscall.Dirent{}.Fileno))
14}
15
16func direntReclen(buf []byte) (uint64, bool) {
17	namlen, ok := direntNamlen(buf)
18	if !ok {
19		return 0, false
20	}
21	return (16 + namlen + 1 + 7) &^ 7, true
22}
23
24func direntNamlen(buf []byte) (uint64, bool) {
25	return readInt(buf, unsafe.Offsetof(syscall.Dirent{}.Namlen), unsafe.Sizeof(syscall.Dirent{}.Namlen))
26}
27
28func direntType(buf []byte) FileMode {
29	off := unsafe.Offsetof(syscall.Dirent{}.Type)
30	if off >= uintptr(len(buf)) {
31		return ^FileMode(0) // unknown
32	}
33	typ := buf[off]
34	switch typ {
35	case syscall.DT_BLK:
36		return ModeDevice
37	case syscall.DT_CHR:
38		return ModeDevice | ModeCharDevice
39	case syscall.DT_DBF:
40		// DT_DBF is "database record file".
41		// fillFileStatFromSys treats as regular file.
42		return 0
43	case syscall.DT_DIR:
44		return ModeDir
45	case syscall.DT_FIFO:
46		return ModeNamedPipe
47	case syscall.DT_LNK:
48		return ModeSymlink
49	case syscall.DT_REG:
50		return 0
51	case syscall.DT_SOCK:
52		return ModeSocket
53	}
54	return ^FileMode(0) // unknown
55}
56