rfjakob/gocryptfs

gccgo compatibility

rfjakob opened this issue · 9 comments

Continues the discussion at #200

$ go.gcc build
# github.com/rfjakob/gocryptfs/internal/syscallcompat
internal/syscallcompat/unix2syscall_linux.go:32:13: error: incompatible types in assignment (cannot use type int64 as type syscall.Timespec_sec_t)
  s.Atim.Sec = u.Atim.Sec
             ^
internal/syscallcompat/unix2syscall_linux.go:33:14: error: incompatible types in assignment (cannot use type int64 as type syscall.Timespec_nsec_t)
  s.Atim.Nsec = u.Atim.Nsec
              ^
internal/syscallcompat/unix2syscall_linux.go:35:13: error: incompatible types in assignment (cannot use type int64 as type syscall.Timespec_sec_t)
  s.Mtim.Sec = u.Mtim.Sec
             ^
internal/syscallcompat/unix2syscall_linux.go:36:14: error: incompatible types in assignment (cannot use type int64 as type syscall.Timespec_nsec_t)
  s.Mtim.Nsec = u.Mtim.Nsec
              ^
internal/syscallcompat/unix2syscall_linux.go:38:13: error: incompatible types in assignment (cannot use type int64 as type syscall.Timespec_sec_t)
  s.Ctim.Sec = u.Ctim.Sec
             ^
internal/syscallcompat/unix2syscall_linux.go:39:14: error: incompatible types in assignment (cannot use type int64 as type syscall.Timespec_nsec_t)
  s.Ctim.Nsec = u.Ctim.Nsec
              ^

How about converting withunix.TimespecToNsec and syscall.NsecToTimespec?

What's the error with getdents?

but the test for emulated getdents fails

Here is the error:

=== RUN   TestGetdents
--- FAIL: TestGetdents (0.01s)
	getdents_test.go:20: testing native getdents
	getdents_test.go:22: testing emulateGetdents
	getdents_test.go:66: opendir : no such file or directory

Can reproduce on amd64, looking into it

1 jakob@brikett:~/go/src/github.com/rfjakob/gocryptfs$ go.gcc test ./internal/syscallcompat/
--- FAIL: TestGetdents (0.02s)
	getdents_test.go:20: testing native getdents
	getdents_test.go:22: testing emulateGetdents
	getdents_test.go:66: opendir : no such file or directory
FAIL
FAIL	github.com/rfjakob/gocryptfs/internal/syscallcompat	0.170s

Uh, libgo does not support reading the directory contents from a file descriptor. This is the error we get thrown: https://github.com/gcc-mirror/gcc/blob/11ce88c6d4dc0f847d8e5d8fac795b7de05ec0e4/libgo/go/os/dir_gccgo.go#L55
Looks like it always want to open the directory by path for some reason.

Note that "file.name" is the empty string because of

f := os.NewFile(uintptr(newFd), "")

Why, for Darwin, are we not using the getdirentries64 system call? Perhaps we could ask libgo to implement it. The call is also present in golang.org/x/sys/unix (but I do not see it documented in either place). Could we maybe use that right now?

Meanwhile, I turned off the problematic emulation (and its test) for Debian. Your great software gocryptfs, which I use every day, is now available on all official Debian release architectures and thus eligible again for inclusion in our testing and stable distributions. Thank you for your excellent product support. Congratulations!

You might like commit 8151222 which skips the broken test when running on gccgo + linux.

As for Darwin and getdirentries64: yes, could work, but I cannot give it enough testing to have confidence in it. emulateGetdents is bulletproof because it only uses the stdlib.

PS: Thank you for your work on the Debian package!