Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrapping FUSE from Go

Tags:

c

go

fuse

I'm playing around with wrapping FUSE with Go. However I've come stuck with how to deal with struct fuse_operations. I can't seem to expose the operations struct by declaring type Operations C.struct_fuse_operations as the members are lower case, and my pure-Go sources would have to use C-hackery to set the members anyway. My first error in this case is "can't set getattr" in what looks to be the Go equivalent of a default copy constructor. My next attempt is to expose an interface that expects GetAttr, ReadLink etc, and then generate C.struct_fuse_operations and bind the function pointers to closures that call the given interface.

This is what I've got (explanation continues after code):

package fuse

// #include <fuse.h>
// #include <stdlib.h>
import "C"

import (
    //"fmt"
    "os"
    "unsafe"
)

type Operations interface {
    GetAttr(string, *os.FileInfo) int
}

func Main(args []string, ops Operations) int {
    argv := make([]*C.char, len(args) + 1)
    for i, s := range args {
        p := C.CString(s)
        defer C.free(unsafe.Pointer(p))
        argv[i] = p
    }
    cop := new(C.struct_fuse_operations)
    cop.getattr = func(*C.char, *C.struct_stat) int {}
    argc := C.int(len(args))
    return int(C.fuse_main_real(argc, &argv[0], cop, C.size_t(unsafe.Sizeof(cop)), nil))
}

package main

import (
    "fmt"
 "fuse"
    "os"
)

type CpfsOps struct {
    a int
}

func (me *CpfsOps) GetAttr(string, *os.FileInfo) int {
    return -1;
}

func main() {
    fmt.Println(os.Args)
    ops := &CpfsOps{}
    fmt.Println("fuse main returned", fuse.Main(os.Args, ops))
}

This gives the following error:

fuse.go:21[fuse.cgo1.go:23]: cannot use func literal (type func(*_Ctype_char, *_Ctype_struct_stat) int) as type *[0]uint8 in assignment

I'm not sure what to pass to these members of C.struct_fuse_operations, and I've seen mention in a few places it's not possible to call from C back into Go code.

If it is possible, what should I do? How can I provide the "default" values for interface functions that acts as though the corresponding C.struct_fuse_operations member is set to NULL?

like image 555
Matt Joiner Avatar asked Nov 14 '22 05:11

Matt Joiner


1 Answers

http://cheesesun.blogspot.com/2010/04/callbacks-in-cgo.html describes a general - if somewhat convoluted - technique. http://groups.google.com/group/golang-nuts/browse_thread/thread/abd0e30dafdbf297?tvc=2&pli=1 describes the problem.

I suspect that if you want to handle the function pointers as anything other than uintptrs, you'll have to hack on cgo.

like image 195
Iain Avatar answered Dec 22 '22 22:12

Iain