From af50095a40f9041b3b38960738837185c26e9419 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Fri, 19 Jan 2018 17:06:40 +0100 Subject: [PATCH] unix: use ParseDirent from syscall Just call syscall's implementation instead of duplicating ParseDirent and the GOOS-specific private functions needed by it. Change-Id: Icf49769390929463323608e093dd2a3d1c0ae4d3 Reviewed-on: https://go-review.googlesource.com/88475 Run-TryBot: Tobias Klauser TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- unix/dirent.go | 89 +-------------------------------------- unix/syscall_darwin.go | 12 ------ unix/syscall_dragonfly.go | 16 ------- unix/syscall_freebsd.go | 12 ------ unix/syscall_linux.go | 16 ------- unix/syscall_netbsd.go | 12 ------ unix/syscall_openbsd.go | 12 ------ unix/syscall_solaris.go | 16 ------- 8 files changed, 2 insertions(+), 183 deletions(-) diff --git a/unix/dirent.go b/unix/dirent.go index bd475812..95fd3531 100644 --- a/unix/dirent.go +++ b/unix/dirent.go @@ -6,97 +6,12 @@ package unix -import "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 isBigEndian { - 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: - _ = b[1] // bounds check hint to compiler; see golang.org/issue/14808 - return uint64(b[1]) | uint64(b[0])<<8 - case 4: - _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808 - return uint64(b[3]) | uint64(b[2])<<8 | uint64(b[1])<<16 | uint64(b[0])<<24 - case 8: - _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808 - return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 | - uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56 - default: - panic("syscall: readInt with unsupported size") - } -} - -func readIntLE(b []byte, size uintptr) uint64 { - switch size { - case 1: - return uint64(b[0]) - case 2: - _ = b[1] // bounds check hint to compiler; see golang.org/issue/14808 - return uint64(b[0]) | uint64(b[1])<<8 - case 4: - _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808 - return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 - case 8: - _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808 - return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | - uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 - default: - panic("syscall: readInt with unsupported size") - } -} +import "syscall" // 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 - } - if ino == 0 { // 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 + return syscall.ParseDirent(buf, max, names) } diff --git a/unix/syscall_darwin.go b/unix/syscall_darwin.go index d6c472a7..1eea3567 100644 --- a/unix/syscall_darwin.go +++ b/unix/syscall_darwin.go @@ -76,18 +76,6 @@ func nametomib(name string) (mib []_C_int, err error) { return buf[0 : n/siz], nil } -func direntIno(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino)) -} - -func direntReclen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) -} - -func direntNamlen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen)) -} - //sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error) func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) } func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) } diff --git a/unix/syscall_dragonfly.go b/unix/syscall_dragonfly.go index 6dfc89a7..17256ec9 100644 --- a/unix/syscall_dragonfly.go +++ b/unix/syscall_dragonfly.go @@ -56,22 +56,6 @@ func nametomib(name string) (mib []_C_int, err error) { return buf[0 : n/siz], nil } -func direntIno(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno)) -} - -func direntReclen(buf []byte) (uint64, bool) { - namlen, ok := direntNamlen(buf) - if !ok { - return 0, false - } - return (16 + namlen + 1 + 7) &^ 7, true -} - -func direntNamlen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen)) -} - //sysnb pipe() (r int, w int, err error) func Pipe(p []int) (err error) { diff --git a/unix/syscall_freebsd.go b/unix/syscall_freebsd.go index b8ecf6c7..44462757 100644 --- a/unix/syscall_freebsd.go +++ b/unix/syscall_freebsd.go @@ -54,18 +54,6 @@ func nametomib(name string) (mib []_C_int, err error) { return buf[0 : n/siz], nil } -func direntIno(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno)) -} - -func direntReclen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) -} - -func direntNamlen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen)) -} - //sysnb pipe() (r int, w int, err error) func Pipe(p []int) (err error) { diff --git a/unix/syscall_linux.go b/unix/syscall_linux.go index 71c58e11..839f1d5c 100644 --- a/unix/syscall_linux.go +++ b/unix/syscall_linux.go @@ -1197,22 +1197,6 @@ func ReadDirent(fd int, buf []byte) (n int, err error) { return Getdents(fd, buf) } -func direntIno(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino)) -} - -func direntReclen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) -} - -func direntNamlen(buf []byte) (uint64, bool) { - reclen, ok := direntReclen(buf) - if !ok { - return 0, false - } - return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true -} - //sys mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) { diff --git a/unix/syscall_netbsd.go b/unix/syscall_netbsd.go index d81106d1..060e5e61 100644 --- a/unix/syscall_netbsd.go +++ b/unix/syscall_netbsd.go @@ -92,18 +92,6 @@ func nametomib(name string) (mib []_C_int, err error) { return mib, nil } -func direntIno(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno)) -} - -func direntReclen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) -} - -func direntNamlen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen)) -} - //sysnb pipe() (fd1 int, fd2 int, err error) func Pipe(p []int) (err error) { if len(p) != 2 { diff --git a/unix/syscall_openbsd.go b/unix/syscall_openbsd.go index 553c2fb8..407d119e 100644 --- a/unix/syscall_openbsd.go +++ b/unix/syscall_openbsd.go @@ -42,18 +42,6 @@ func nametomib(name string) (mib []_C_int, err error) { return nil, EINVAL } -func direntIno(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno)) -} - -func direntReclen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) -} - -func direntNamlen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen)) -} - //sysnb pipe(p *[2]_C_int) (err error) func Pipe(p []int) (err error) { if len(p) != 2 { diff --git a/unix/syscall_solaris.go b/unix/syscall_solaris.go index 9dc01e74..a87aebfe 100644 --- a/unix/syscall_solaris.go +++ b/unix/syscall_solaris.go @@ -34,22 +34,6 @@ type SockaddrDatalink struct { raw RawSockaddrDatalink } -func direntIno(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino)) -} - -func direntReclen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) -} - -func direntNamlen(buf []byte) (uint64, bool) { - reclen, ok := direntReclen(buf) - if !ok { - return 0, false - } - return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true -} - //sysnb pipe(p *[2]_C_int) (n int, err error) func Pipe(p []int) (err error) {