Commit 90605253 authored by Jakob Unterwurzacher's avatar Jakob Unterwurzacher Committed by Han-Wen Nienhuys

Switch from syscall.Getdents to unix.Getdents

On mips64le, syscall.Getdents() and struct syscall.Dirent do
not fit together, causing our parseDirents() implementation to
return garbage ( see https://github.com/rfjakob/gocryptfs/issues/200
and https://github.com/golang/go/issues/23624 ).

Switch to unix.Getdents which does not have this problem -
the next Go release with the syscall package fixes is too
far away, and will take time to trickle into distros.

This issue has been reported by Debian maintainer
Felix Lechner.
parent 6975cb38
......@@ -11,6 +11,8 @@ import (
"testing"
"time"
"golang.org/x/sys/unix"
"github.com/hanwen/go-fuse/fuse"
)
......@@ -143,7 +145,7 @@ func TestFallocate(t *testing.T) {
}
}
// Check that "." and ".." exists. syscall.Getdents is linux specific.
// Check that "." and ".." exists. unix.Getdents is linux specific.
func TestSpecialEntries(t *testing.T) {
tc := NewTestCase(t)
defer tc.Cleanup()
......@@ -154,7 +156,7 @@ func TestSpecialEntries(t *testing.T) {
}
defer d.Close()
buf := make([]byte, 100)
n, err := syscall.Getdents(int(d.Fd()), buf)
n, err := unix.Getdents(int(d.Fd()), buf)
if n == 0 {
t.Errorf("directory is empty, entries '.' and '..' are missing")
}
......@@ -180,7 +182,7 @@ func TestReaddirInodes(t *testing.T) {
buf := make([]byte, 100)
// readdir(3) use getdents64(2) internally which returns linux_dirent64
// structures. We don't have readdir(3) so we call getdents64(2) directly.
n, err := syscall.Getdents(int(d.Fd()), buf)
n, err := unix.Getdents(int(d.Fd()), buf)
if n == 0 {
t.Error("empty directory - we need at least one file")
}
......
......@@ -13,6 +13,8 @@ import (
"syscall"
"testing"
"unsafe"
"golang.org/x/sys/unix"
)
func clen(n []byte) int {
......@@ -34,7 +36,7 @@ type CDirent struct {
func parseDirents(buf []byte) []CDirent {
var result []CDirent
for len(buf) > 0 {
de := *(*syscall.Dirent)(unsafe.Pointer(&buf[0]))
de := *(*unix.Dirent)(unsafe.Pointer(&buf[0]))
buf = buf[de.Reclen:]
bytes := (*[10000]byte)(unsafe.Pointer(&de.Name[0]))
var name = string(bytes[0:clen(bytes[:])])
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment