summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/mattermost/rsc/fuse/mount_darwin.go
blob: 5e2caaa764527f5fba1307895d02924d79cf32f7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// Copyright 2011 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// TODO: Rewrite using package syscall not cgo

package fuse

/*

// Adapted from Plan 9 from User Space's src/cmd/9pfuse/fuse.c,
// which carries this notice:
//
// The files in this directory are subject to the following license.
// 
// The author of this software is Russ Cox.
// 
//         Copyright (c) 2006 Russ Cox
// 
// Permission to use, copy, modify, and distribute this software for any
// purpose without fee is hereby granted, provided that this entire notice
// is included in all copies of any software which is or includes a copy
// or modification of this software and in all copies of the supporting
// documentation for such software.
// 
// THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
// WARRANTY.  IN PARTICULAR, THE AUTHOR MAKES NO REPRESENTATION OR WARRANTY
// OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS SOFTWARE OR ITS
// FITNESS FOR ANY PARTICULAR PURPOSE.

#include <stdlib.h>
#include <sys/param.h>
#include <sys/mount.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>

#define nil ((void*)0)

static int
mountfuse(char *mtpt, char **err)
{
	int i, pid, fd, r;
	char buf[200];
	struct vfsconf vfs;
	char *f;

	if(getvfsbyname("fusefs", &vfs) < 0){
		if(access(f="/Library/Filesystems/osxfusefs.fs"
			"/Support/load_osxfusefs", 0) < 0){
		         *err = strdup("cannot find load_fusefs");
		   	return -1;
		}
		if((r=system(f)) < 0){
			snprintf(buf, sizeof buf, "%s: %s", f, strerror(errno));
			*err = strdup(buf);
			return -1;
		}
		if(r != 0){
			snprintf(buf, sizeof buf, "load_fusefs failed: exit %d", r);
			*err = strdup(buf);
			return -1;
		}
		if(getvfsbyname("osxfusefs", &vfs) < 0){
			snprintf(buf, sizeof buf, "getvfsbyname osxfusefs: %s", strerror(errno));
			*err = strdup(buf);
			return -1;
		}
	}

	// Look for available FUSE device.
	for(i=0;; i++){
		snprintf(buf, sizeof buf, "/dev/osxfuse%d", i);
		if(access(buf, 0) < 0){
			*err = strdup("no available fuse devices");
			return -1;
		}
		if((fd = open(buf, O_RDWR)) >= 0)
			break;
	}

	pid = fork();
	if(pid < 0)
		return -1;
	if(pid == 0){
		snprintf(buf, sizeof buf, "%d", fd);
		setenv("MOUNT_FUSEFS_CALL_BY_LIB", "", 1);
		// Different versions of MacFUSE put the
		// mount_fusefs binary in different places.
		// Try all.
		// Leopard location
		setenv("MOUNT_FUSEFS_DAEMON_PATH",
			   "/Library/Filesystems/osxfusefs.fs/Support/mount_osxfusefs", 1);
		execl("/Library/Filesystems/osxfusefs.fs/Support/mount_osxfusefs",
			  "mount_osxfusefs",
			  "-o", "iosize=4096", buf, mtpt, nil);
		fprintf(stderr, "exec mount_osxfusefs: %s\n", strerror(errno));
		_exit(1);
	}
	return fd;
}

*/
import "C"

import "unsafe"

func mount(dir string) (int, string) {
	errp := (**C.char)(C.malloc(16))
	*errp = nil
	defer C.free(unsafe.Pointer(errp))
	cdir := C.CString(dir)
	defer C.free(unsafe.Pointer(cdir))
	fd := C.mountfuse(cdir, errp)
	var err string
	if *errp != nil {
		err = C.GoString(*errp)
	}
	return int(fd), err
}