Skip to content

Commit 0acc17d

Browse files
committed
freebsd port
1 parent ea66f98 commit 0acc17d

File tree

8 files changed

+113
-19
lines changed

8 files changed

+113
-19
lines changed

README.md

+12-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
Cgofuse is a cross-platform FUSE library for Go. It is implemented using [cgo](https://golang.org/cmd/cgo/) and can be ported to any platform that has a FUSE implementation.
99

10-
Cgofuse currently runs on **OSX**, **Linux** and **Windows** (using [WinFsp](https://github.com/billziss-gh/winfsp)).
10+
Cgofuse currently runs on **OSX**, **FreeBSD**, **Linux** and **Windows** (using [WinFsp](https://github.com/billziss-gh/winfsp)).
1111

1212
## How to build
1313

@@ -19,13 +19,22 @@ Cgofuse currently runs on **OSX**, **Linux** and **Windows** (using [WinFsp](htt
1919
$ go install -v ./fuse ./examples/memfs ./examples/passthrough
2020
```
2121
22+
**FreeBSD**
23+
- Prerequisites: fusefs-libs, clang
24+
- Build:
25+
```
26+
$ cd cgofuse
27+
$ go install -v ./fuse ./examples/memfs ./examples/passthrough
28+
```
29+
2230
**Linux**
2331
- Prerequisites: libfuse-dev, gcc
2432
- Build:
2533
```
2634
$ cd cgofuse
2735
$ go install -v ./fuse ./examples/memfs ./examples/passthrough
2836
```
37+
2938
**Windows**
3039
- Prerequisites: [WinFsp](https://github.com/billziss-gh/winfsp), gcc (e.g. from [Mingw-builds](http://mingw-w64.org/doku.php/download))
3140
- Build:
@@ -49,6 +58,8 @@ You can easily cross-compile your project using [xgo](https://github.com/karalab
4958
--targets=darwin/386,darwin/amd64,linux/386,linux/amd64,windows/386,windows/amd64 .
5059
```
5160
61+
Cross-compilation only works for OSX, Linux and Windows only.
62+
5263
## How to use
5364
5465
User mode file systems are expected to implement `fuse.FileSystemInterface`. To make implementation simpler a file system can embed ("inherit") a `fuse.FileSystemBase` which provides default implementations for all operations. To mount a file system one must instantiate a `fuse.FileSystemHost` using `fuse.NewFileSystemHost`.

examples/passthrough/passthrough.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// +build darwin linux
1+
// +build darwin freebsd linux
22

33
/*
44
* passthrough.go

examples/passthrough/port_darwin.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// +build darwin
22

33
/*
4-
* struct_darwin.go
4+
* port_darwin.go
55
*
66
* Copyright 2017 Bill Zissimopoulos
77
*/

examples/passthrough/port_freebsd.go

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// +build freebsd
2+
3+
/*
4+
* port_freebsd.go
5+
*
6+
* Copyright 2017 Bill Zissimopoulos
7+
*/
8+
/*
9+
* This file is part of Cgofuse.
10+
*
11+
* It is licensed under the MIT license. The full license text can be found
12+
* in the License.txt file at the root of this project.
13+
*/
14+
15+
package main
16+
17+
import (
18+
"syscall"
19+
20+
"github.com/billziss-gh/cgofuse/fuse"
21+
)
22+
23+
func setuidgid() func() {
24+
euid := syscall.Geteuid()
25+
if 0 == euid {
26+
uid, gid, _ := fuse.Getcontext()
27+
egid := syscall.Getegid()
28+
syscall.Setegid(int(gid))
29+
syscall.Seteuid(int(uid))
30+
return func() {
31+
syscall.Seteuid(euid)
32+
syscall.Setegid(egid)
33+
}
34+
}
35+
return func() {
36+
}
37+
}
38+
39+
func copyFusestatfsFromGostatfs(dst *fuse.Statfs_t, src *syscall.Statfs_t) {
40+
*dst = fuse.Statfs_t{}
41+
dst.Bsize = uint64(src.Bsize)
42+
dst.Frsize = 1
43+
dst.Blocks = uint64(src.Blocks)
44+
dst.Bfree = uint64(src.Bfree)
45+
dst.Bavail = uint64(src.Bavail)
46+
dst.Files = uint64(src.Files)
47+
dst.Ffree = uint64(src.Ffree)
48+
dst.Favail = uint64(src.Ffree)
49+
dst.Namemax = 255 //uint64(src.Namelen)
50+
}
51+
52+
func copyFusestatFromGostat(dst *fuse.Stat_t, src *syscall.Stat_t) {
53+
*dst = fuse.Stat_t{}
54+
dst.Dev = uint64(src.Dev)
55+
dst.Ino = uint64(src.Ino)
56+
dst.Mode = uint32(src.Mode)
57+
dst.Nlink = uint32(src.Nlink)
58+
dst.Uid = uint32(src.Uid)
59+
dst.Gid = uint32(src.Gid)
60+
dst.Rdev = uint64(src.Rdev)
61+
dst.Size = int64(src.Size)
62+
dst.Atim.Sec, dst.Atim.Nsec = src.Atimespec.Sec, src.Atimespec.Nsec
63+
dst.Mtim.Sec, dst.Mtim.Nsec = src.Mtimespec.Sec, src.Mtimespec.Nsec
64+
dst.Ctim.Sec, dst.Ctim.Nsec = src.Ctimespec.Sec, src.Ctimespec.Nsec
65+
dst.Blksize = int64(src.Blksize)
66+
dst.Blocks = int64(src.Blocks)
67+
dst.Birthtim.Sec, dst.Birthtim.Nsec = src.Birthtimespec.Sec, src.Birthtimespec.Nsec
68+
}

examples/passthrough/port_linux.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// +build linux
22

33
/*
4-
* struct_linux.go
4+
* port_linux.go
55
*
66
* Copyright 2017 Bill Zissimopoulos
77
*/

fuse/fsop.go

+18-6
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@
2424
package fuse
2525

2626
/*
27-
#if !(defined(__APPLE__) || defined(__linux__) || defined(_WIN32))
27+
#if !(defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__) || defined(_WIN32))
2828
#error platform not supported
2929
#endif
3030
31-
#if defined(__APPLE__) || defined(__linux__)
31+
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__)
3232
3333
#include <errno.h>
3434
#include <fcntl.h>
@@ -131,14 +131,26 @@ package fuse
131131
132132
#if defined(__linux__) || defined(_WIN32)
133133
// incantation needed for cgo to figure out "kind of name" for ENOATTR
134-
#define ENOATTR ((int)ENODATA)
134+
#define ENOATTR ((int)ENODATA)
135+
136+
#elif defined(__FreeBSD__)
137+
138+
// ETIME: see https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=225324
139+
// ENODATA: the following is not strictly correct but a lot of project
140+
// assume that ENODATA == ENOATTR, just because Linux does so.
141+
// ENOSTR, ENOSR: these are not defined anywhere; convert to EINVAL
142+
#define ETIME ETIMEDOUT
143+
#define ENODATA ENOATTR
144+
#define ENOSTR EINVAL
145+
#define ENOSR EINVAL
146+
135147
#endif
136148
137149
#if defined(__APPLE__) || defined(__linux__)
138150
#include <sys/xattr.h>
139-
#elif defined(_WIN32)
140-
#define XATTR_CREATE 1
141-
#define XATTR_REPLACE 2
151+
#elif defined(__FreeBSD__) || defined(_WIN32)
152+
#define XATTR_CREATE 1
153+
#define XATTR_REPLACE 2
142154
#endif
143155
*/
144156
import "C"

fuse/host.go

+11-8
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,25 @@ package fuse
1616
#cgo darwin CFLAGS: -DFUSE_USE_VERSION=28 -D_FILE_OFFSET_BITS=64 -I/usr/local/include/osxfuse/fuse
1717
#cgo darwin LDFLAGS: -L/usr/local/lib -losxfuse
1818
19+
#cgo freebsd CFLAGS: -DFUSE_USE_VERSION=28 -D_FILE_OFFSET_BITS=64 -I/usr/local/include/fuse
20+
#cgo freebsd LDFLAGS: -L/usr/local/lib -lfuse
21+
1922
#cgo linux CFLAGS: -DFUSE_USE_VERSION=28 -D_FILE_OFFSET_BITS=64 -I/usr/include/fuse
2023
#cgo linux LDFLAGS: -lfuse
2124
2225
// Use `set CPATH=C:\Program Files (x86)\WinFsp\inc\fuse` on Windows.
2326
// The flag `I/usr/local/include/winfsp` only works on xgo and docker.
2427
#cgo windows CFLAGS: -DFUSE_USE_VERSION=28 -I/usr/local/include/winfsp
2528
26-
#if !(defined(__APPLE__) || defined(__linux__) || defined(_WIN32))
29+
#if !(defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__) || defined(_WIN32))
2730
#error platform not supported
2831
#endif
2932
3033
#include <stdbool.h>
3134
#include <stdlib.h>
3235
#include <string.h>
3336
34-
#if defined(__APPLE__) || defined(__linux__)
37+
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__)
3538
3639
#include <spawn.h>
3740
#include <sys/mount.h>
@@ -191,7 +194,7 @@ static PVOID cgofuse_init_winfsp(VOID)
191194
192195
#endif
193196
194-
#if defined(__APPLE__) || defined(__linux__)
197+
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__)
195198
typedef struct stat fuse_stat_t;
196199
typedef struct statvfs fuse_statvfs_t;
197200
typedef struct timespec fuse_timespec_t;
@@ -257,7 +260,7 @@ static inline void hostAsgnCconninfo(struct fuse_conn_info *conn,
257260
#if defined(__APPLE__)
258261
if (capCaseInsensitive)
259262
FUSE_ENABLE_CASE_INSENSITIVE(conn);
260-
#elif defined(__linux__)
263+
#elif defined(__FreeBSD__) || defined(__linux__)
261264
#elif defined(_WIN32)
262265
#if defined(FSP_FUSE_CAP_STAT_EX)
263266
conn->want |= conn->capable & FSP_FUSE_CAP_STAT_EX;
@@ -398,15 +401,15 @@ static int _hostGetxattr(char *path, char *name, char *value, size_t size,
398401
399402
static void hostStaticInit(void)
400403
{
401-
#if defined(__APPLE__) || defined(__linux__)
404+
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__)
402405
#elif defined(_WIN32)
403406
InitializeCriticalSection(&cgofuse_lock);
404407
#endif
405408
}
406409
407410
static int hostFuseInit(void)
408411
{
409-
#if defined(__APPLE__) || defined(__linux__)
412+
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__)
410413
return 1;
411414
#elif defined(_WIN32)
412415
return 0 != cgofuse_init_fast(0);
@@ -502,10 +505,10 @@ static int hostMount(int argc, char *argv[], void *data)
502505
503506
static int hostUnmount(struct fuse *fuse, char *mountpoint)
504507
{
505-
#if defined(__APPLE__)
508+
#if defined(__APPLE__) || defined(__FreeBSD__)
506509
if (0 == mountpoint)
507510
return 0;
508-
// darwin: unmount is available to non-root
511+
// darwin,freebsd: unmount is available to non-root
509512
return 0 == unmount(mountpoint, MNT_FORCE);
510513
#elif defined(__linux__)
511514
if (0 == mountpoint)

fuse/host_unix_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// +build darwin linux
1+
// +build darwin freebsd linux
22

33
/*
44
* host_unix_test.go

0 commit comments

Comments
 (0)