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

     1  // Copyright 2011 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  // TODO: Rewrite using package syscall not cgo
     6  
     7  package fuse
     8  
     9  /*
    10  
    11  // Adapted from Plan 9 from User Space's src/cmd/9pfuse/fuse.c,
    12  // which carries this notice:
    13  //
    14  // The files in this directory are subject to the following license.
    15  // 
    16  // The author of this software is Russ Cox.
    17  // 
    18  //         Copyright (c) 2006 Russ Cox
    19  // 
    20  // Permission to use, copy, modify, and distribute this software for any
    21  // purpose without fee is hereby granted, provided that this entire notice
    22  // is included in all copies of any software which is or includes a copy
    23  // or modification of this software and in all copies of the supporting
    24  // documentation for such software.
    25  // 
    26  // THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
    27  // WARRANTY.  IN PARTICULAR, THE AUTHOR MAKES NO REPRESENTATION OR WARRANTY
    28  // OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS SOFTWARE OR ITS
    29  // FITNESS FOR ANY PARTICULAR PURPOSE.
    30  
    31  #include <stdlib.h>
    32  #include <sys/param.h>
    33  #include <sys/mount.h>
    34  #include <unistd.h>
    35  #include <string.h>
    36  #include <stdio.h>
    37  #include <errno.h>
    38  #include <fcntl.h>
    39  
    40  #define nil ((void*)0)
    41  
    42  static int
    43  mountfuse(char *mtpt, char **err)
    44  {
    45  	int i, pid, fd, r;
    46  	char buf[200];
    47  	struct vfsconf vfs;
    48  	char *f;
    49  
    50  	if(getvfsbyname("fusefs", &vfs) < 0){
    51  		if(access(f="/Library/Filesystems/osxfusefs.fs"
    52  			"/Support/load_osxfusefs", 0) < 0){
    53  		         *err = strdup("cannot find load_fusefs");
    54  		   	return -1;
    55  		}
    56  		if((r=system(f)) < 0){
    57  			snprintf(buf, sizeof buf, "%s: %s", f, strerror(errno));
    58  			*err = strdup(buf);
    59  			return -1;
    60  		}
    61  		if(r != 0){
    62  			snprintf(buf, sizeof buf, "load_fusefs failed: exit %d", r);
    63  			*err = strdup(buf);
    64  			return -1;
    65  		}
    66  		if(getvfsbyname("osxfusefs", &vfs) < 0){
    67  			snprintf(buf, sizeof buf, "getvfsbyname osxfusefs: %s", strerror(errno));
    68  			*err = strdup(buf);
    69  			return -1;
    70  		}
    71  	}
    72  
    73  	// Look for available FUSE device.
    74  	for(i=0;; i++){
    75  		snprintf(buf, sizeof buf, "/dev/osxfuse%d", i);
    76  		if(access(buf, 0) < 0){
    77  			*err = strdup("no available fuse devices");
    78  			return -1;
    79  		}
    80  		if((fd = open(buf, O_RDWR)) >= 0)
    81  			break;
    82  	}
    83  
    84  	pid = fork();
    85  	if(pid < 0)
    86  		return -1;
    87  	if(pid == 0){
    88  		snprintf(buf, sizeof buf, "%d", fd);
    89  		setenv("MOUNT_FUSEFS_CALL_BY_LIB", "", 1);
    90  		// Different versions of MacFUSE put the
    91  		// mount_fusefs binary in different places.
    92  		// Try all.
    93  		// Leopard location
    94  		setenv("MOUNT_FUSEFS_DAEMON_PATH",
    95  			   "/Library/Filesystems/osxfusefs.fs/Support/mount_osxfusefs", 1);
    96  		execl("/Library/Filesystems/osxfusefs.fs/Support/mount_osxfusefs",
    97  			  "mount_osxfusefs",
    98  			  "-o", "iosize=4096", buf, mtpt, nil);
    99  		fprintf(stderr, "exec mount_osxfusefs: %s\n", strerror(errno));
   100  		_exit(1);
   101  	}
   102  	return fd;
   103  }
   104  
   105  */
   106  import "C"
   107  
   108  import "unsafe"
   109  
   110  func mount(dir string) (int, string) {
   111  	errp := (**C.char)(C.malloc(16))
   112  	*errp = nil
   113  	defer C.free(unsafe.Pointer(errp))
   114  	cdir := C.CString(dir)
   115  	defer C.free(unsafe.Pointer(cdir))
   116  	fd := C.mountfuse(cdir, errp)
   117  	var err string
   118  	if *errp != nil {
   119  		err = C.GoString(*errp)
   120  	}
   121  	return int(fd), err
   122  }