From cbb13ba8d29c65dd5661be449c56563edcb7f5a1 Mon Sep 17 00:00:00 2001 From: Glonee Date: Thu, 16 Nov 2023 22:05:35 +0800 Subject: [PATCH] fuse: parse socket control message using the standard library make mount procedure cleaner by using standard library to parse socker control message Change-Id: Ic52f5a0e2ddda40e680e341e35fb9b4158ba3324 --- fuse/mount.go | 48 ++++++++++++++++++++++++++++++++++++++++++++ fuse/mount_darwin.go | 28 -------------------------- fuse/mount_linux.go | 28 -------------------------- 3 files changed, 48 insertions(+), 56 deletions(-) create mode 100644 fuse/mount.go diff --git a/fuse/mount.go b/fuse/mount.go new file mode 100644 index 000000000..874d9c459 --- /dev/null +++ b/fuse/mount.go @@ -0,0 +1,48 @@ +package fuse + +import ( + "fmt" + "net" + "os" + "syscall" +) + +func getConnection(local *os.File) (int, error) { + conn, err := net.FileConn(local) + if err != nil { + return 0, err + } + defer conn.Close() + unixConn := conn.(*net.UnixConn) + + var data [4]byte + control := make([]byte, 4*256) + + _, oobn, _, _, err := unixConn.ReadMsgUnix(data[:], control[:]) + if err != nil { + return 0, err + } + + messages, err := syscall.ParseSocketControlMessage(control[:oobn]) + if err != nil { + return 0, err + } + if len(messages) != 1 { + return 0, fmt.Errorf("getConnection: expect 1 control message, got %#v", messages) + } + message := messages[0] + + fds, err := syscall.ParseUnixRights(&message) + if err != nil { + return 0, err + } + if len(fds) != 1 { + return 0, fmt.Errorf("getConnection: expect 1 fd, got %#v", fds) + } + fd := fds[0] + + if fd < 0 { + return 0, fmt.Errorf("getConnection: fd < 0: %d", fd) + } + return fd, nil +} diff --git a/fuse/mount_darwin.go b/fuse/mount_darwin.go index 1112799bb..cabdaa29c 100644 --- a/fuse/mount_darwin.go +++ b/fuse/mount_darwin.go @@ -11,7 +11,6 @@ import ( "os/exec" "strings" "syscall" - "unsafe" ) func unixgramSocketpair() (l, r *os.File, err error) { @@ -90,33 +89,6 @@ func unmount(dir string, opts *MountOptions) error { return syscall.Unmount(dir, 0) } -func getConnection(local *os.File) (int, error) { - var data [4]byte - control := make([]byte, 4*256) - - // n, oobn, recvflags, from, errno - todo: error checking. - _, oobn, _, _, - err := syscall.Recvmsg( - int(local.Fd()), data[:], control[:], 0) - if err != nil { - return 0, err - } - - message := *(*syscall.Cmsghdr)(unsafe.Pointer(&control[0])) - fd := *(*int32)(unsafe.Pointer(uintptr(unsafe.Pointer(&control[0])) + syscall.SizeofCmsghdr)) - - if message.Type != syscall.SCM_RIGHTS { - return 0, fmt.Errorf("getConnection: recvmsg returned wrong control type: %d", message.Type) - } - if oobn <= syscall.SizeofCmsghdr { - return 0, fmt.Errorf("getConnection: too short control message. Length: %d", oobn) - } - if fd < 0 { - return 0, fmt.Errorf("getConnection: fd < 0: %d", fd) - } - return int(fd), nil -} - func fusermountBinary() (string, error) { binPaths := []string{ "/Library/Filesystems/macfuse.fs/Contents/Resources/mount_macfuse", diff --git a/fuse/mount_linux.go b/fuse/mount_linux.go index c6abf035e..96111d3b7 100644 --- a/fuse/mount_linux.go +++ b/fuse/mount_linux.go @@ -12,7 +12,6 @@ import ( "path" "strings" "syscall" - "unsafe" ) func unixgramSocketpair() (l, r *os.File, err error) { @@ -203,33 +202,6 @@ func unmount(mountPoint string, opts *MountOptions) (err error) { return err } -func getConnection(local *os.File) (int, error) { - var data [4]byte - control := make([]byte, 4*256) - - // n, oobn, recvflags, from, errno - todo: error checking. - _, oobn, _, _, - err := syscall.Recvmsg( - int(local.Fd()), data[:], control[:], 0) - if err != nil { - return 0, err - } - - message := *(*syscall.Cmsghdr)(unsafe.Pointer(&control[0])) - fd := *(*int32)(unsafe.Pointer(uintptr(unsafe.Pointer(&control[0])) + syscall.SizeofCmsghdr)) - - if message.Type != 1 { - return 0, fmt.Errorf("getConnection: recvmsg returned wrong control type: %d", message.Type) - } - if oobn <= syscall.SizeofCmsghdr { - return 0, fmt.Errorf("getConnection: too short control message. Length: %d", oobn) - } - if fd < 0 { - return 0, fmt.Errorf("getConnection: fd < 0: %d", fd) - } - return int(fd), nil -} - // lookPathFallback - search binary in PATH and, if that fails, // in fallbackDir. This is useful if PATH is possible empty. func lookPathFallback(file string, fallbackDir string) (string, error) {