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 }