github.com/slspeek/camlistore_namedsearch@v0.0.0-20140519202248-ed6f70f7721a/third_party/bazil.org/fuse/mount_linux.go (about)

     1  package fuse
     2  
     3  import (
     4  	"fmt"
     5  	"net"
     6  	"os"
     7  	"os/exec"
     8  	"syscall"
     9  )
    10  
    11  func mount(dir string) (fusefd int, errmsg string) {
    12  	fds, err := syscall.Socketpair(syscall.AF_FILE, syscall.SOCK_STREAM, 0)
    13  	if err != nil {
    14  		return -1, fmt.Sprintf("socketpair error: %v", err)
    15  	}
    16  	defer syscall.Close(fds[0])
    17  	defer syscall.Close(fds[1])
    18  
    19  	cmd := exec.Command("fusermount", "--", dir)
    20  	cmd.Env = append(os.Environ(), "_FUSE_COMMFD=3")
    21  
    22  	writeFile := os.NewFile(uintptr(fds[0]), "fusermount-child-writes")
    23  	defer writeFile.Close()
    24  	cmd.ExtraFiles = []*os.File{writeFile}
    25  
    26  	out, err := cmd.CombinedOutput()
    27  	if len(out) > 0 || err != nil {
    28  		return -1, fmt.Sprintf("fusermount: %q, %v", out, err)
    29  	}
    30  
    31  	readFile := os.NewFile(uintptr(fds[1]), "fusermount-parent-reads")
    32  	defer readFile.Close()
    33  	c, err := net.FileConn(readFile)
    34  	if err != nil {
    35  		return -1, fmt.Sprintf("FileConn from fusermount socket: %v", err)
    36  	}
    37  	defer c.Close()
    38  
    39  	uc, ok := c.(*net.UnixConn)
    40  	if !ok {
    41  		return -1, fmt.Sprintf("unexpected FileConn type; expected UnixConn, got %T", c)
    42  	}
    43  
    44  	buf := make([]byte, 32) // expect 1 byte
    45  	oob := make([]byte, 32) // expect 24 bytes
    46  	_, oobn, _, _, err := uc.ReadMsgUnix(buf, oob)
    47  	scms, err := syscall.ParseSocketControlMessage(oob[:oobn])
    48  	if err != nil {
    49  		return -1, fmt.Sprintf("ParseSocketControlMessage: %v", err)
    50  	}
    51  	if len(scms) != 1 {
    52  		return -1, fmt.Sprintf("expected 1 SocketControlMessage; got scms = %#v", scms)
    53  	}
    54  	scm := scms[0]
    55  	gotFds, err := syscall.ParseUnixRights(&scm)
    56  	if err != nil {
    57  		return -1, fmt.Sprintf("syscall.ParseUnixRights: %v", err)
    58  	}
    59  	if len(gotFds) != 1 {
    60  		return -1, fmt.Sprintf("wanted 1 fd; got %#v", gotFds)
    61  	}
    62  	return gotFds[0], ""
    63  }