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 }