github.com/olivere/camlistore@v0.0.0-20140121221811-1b7ac2da0199/third_party/code.google.com/p/rsc/fuse/mount_linux.go (about)

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