Skip to content

Commit

Permalink
freebsd port
Browse files Browse the repository at this point in the history
  • Loading branch information
billziss-gh committed May 20, 2018
1 parent ea66f98 commit 0acc17d
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 19 deletions.
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

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.

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

## How to build

Expand All @@ -19,13 +19,22 @@ Cgofuse currently runs on **OSX**, **Linux** and **Windows** (using [WinFsp](htt
$ go install -v ./fuse ./examples/memfs ./examples/passthrough
```

**FreeBSD**
- Prerequisites: fusefs-libs, clang
- Build:
```
$ cd cgofuse
$ go install -v ./fuse ./examples/memfs ./examples/passthrough
```

**Linux**
- Prerequisites: libfuse-dev, gcc
- Build:
```
$ cd cgofuse
$ go install -v ./fuse ./examples/memfs ./examples/passthrough
```

**Windows**
- Prerequisites: [WinFsp](https://github.com/billziss-gh/winfsp), gcc (e.g. from [Mingw-builds](http://mingw-w64.org/doku.php/download))
- Build:
Expand All @@ -49,6 +58,8 @@ You can easily cross-compile your project using [xgo](https://github.com/karalab
--targets=darwin/386,darwin/amd64,linux/386,linux/amd64,windows/386,windows/amd64 .
```

Cross-compilation only works for OSX, Linux and Windows only.

## How to use

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`.
Expand Down
2 changes: 1 addition & 1 deletion examples/passthrough/passthrough.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// +build darwin linux
// +build darwin freebsd linux

/*
* passthrough.go
Expand Down
2 changes: 1 addition & 1 deletion examples/passthrough/port_darwin.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// +build darwin

/*
* struct_darwin.go
* port_darwin.go
*
* Copyright 2017 Bill Zissimopoulos
*/
Expand Down
68 changes: 68 additions & 0 deletions examples/passthrough/port_freebsd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// +build freebsd

/*
* port_freebsd.go
*
* Copyright 2017 Bill Zissimopoulos
*/
/*
* This file is part of Cgofuse.
*
* It is licensed under the MIT license. The full license text can be found
* in the License.txt file at the root of this project.
*/

package main

import (
"syscall"

"github.com/billziss-gh/cgofuse/fuse"
)

func setuidgid() func() {
euid := syscall.Geteuid()
if 0 == euid {
uid, gid, _ := fuse.Getcontext()
egid := syscall.Getegid()
syscall.Setegid(int(gid))
syscall.Seteuid(int(uid))
return func() {
syscall.Seteuid(euid)
syscall.Setegid(egid)
}
}
return func() {
}
}

func copyFusestatfsFromGostatfs(dst *fuse.Statfs_t, src *syscall.Statfs_t) {
*dst = fuse.Statfs_t{}
dst.Bsize = uint64(src.Bsize)
dst.Frsize = 1
dst.Blocks = uint64(src.Blocks)
dst.Bfree = uint64(src.Bfree)
dst.Bavail = uint64(src.Bavail)
dst.Files = uint64(src.Files)
dst.Ffree = uint64(src.Ffree)
dst.Favail = uint64(src.Ffree)
dst.Namemax = 255 //uint64(src.Namelen)
}

func copyFusestatFromGostat(dst *fuse.Stat_t, src *syscall.Stat_t) {
*dst = fuse.Stat_t{}
dst.Dev = uint64(src.Dev)
dst.Ino = uint64(src.Ino)
dst.Mode = uint32(src.Mode)
dst.Nlink = uint32(src.Nlink)
dst.Uid = uint32(src.Uid)
dst.Gid = uint32(src.Gid)
dst.Rdev = uint64(src.Rdev)
dst.Size = int64(src.Size)
dst.Atim.Sec, dst.Atim.Nsec = src.Atimespec.Sec, src.Atimespec.Nsec
dst.Mtim.Sec, dst.Mtim.Nsec = src.Mtimespec.Sec, src.Mtimespec.Nsec
dst.Ctim.Sec, dst.Ctim.Nsec = src.Ctimespec.Sec, src.Ctimespec.Nsec
dst.Blksize = int64(src.Blksize)
dst.Blocks = int64(src.Blocks)
dst.Birthtim.Sec, dst.Birthtim.Nsec = src.Birthtimespec.Sec, src.Birthtimespec.Nsec
}
2 changes: 1 addition & 1 deletion examples/passthrough/port_linux.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// +build linux

/*
* struct_linux.go
* port_linux.go
*
* Copyright 2017 Bill Zissimopoulos
*/
Expand Down
24 changes: 18 additions & 6 deletions fuse/fsop.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@
package fuse

/*
#if !(defined(__APPLE__) || defined(__linux__) || defined(_WIN32))
#if !(defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__) || defined(_WIN32))
#error platform not supported
#endif
#if defined(__APPLE__) || defined(__linux__)
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__)
#include <errno.h>
#include <fcntl.h>
Expand Down Expand Up @@ -131,14 +131,26 @@ package fuse
#if defined(__linux__) || defined(_WIN32)
// incantation needed for cgo to figure out "kind of name" for ENOATTR
#define ENOATTR ((int)ENODATA)
#define ENOATTR ((int)ENODATA)
#elif defined(__FreeBSD__)
// ETIME: see https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=225324
// ENODATA: the following is not strictly correct but a lot of project
// assume that ENODATA == ENOATTR, just because Linux does so.
// ENOSTR, ENOSR: these are not defined anywhere; convert to EINVAL
#define ETIME ETIMEDOUT
#define ENODATA ENOATTR
#define ENOSTR EINVAL
#define ENOSR EINVAL
#endif
#if defined(__APPLE__) || defined(__linux__)
#include <sys/xattr.h>
#elif defined(_WIN32)
#define XATTR_CREATE 1
#define XATTR_REPLACE 2
#elif defined(__FreeBSD__) || defined(_WIN32)
#define XATTR_CREATE 1
#define XATTR_REPLACE 2
#endif
*/
import "C"
Expand Down
19 changes: 11 additions & 8 deletions fuse/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,25 @@ package fuse
#cgo darwin CFLAGS: -DFUSE_USE_VERSION=28 -D_FILE_OFFSET_BITS=64 -I/usr/local/include/osxfuse/fuse
#cgo darwin LDFLAGS: -L/usr/local/lib -losxfuse
#cgo freebsd CFLAGS: -DFUSE_USE_VERSION=28 -D_FILE_OFFSET_BITS=64 -I/usr/local/include/fuse
#cgo freebsd LDFLAGS: -L/usr/local/lib -lfuse
#cgo linux CFLAGS: -DFUSE_USE_VERSION=28 -D_FILE_OFFSET_BITS=64 -I/usr/include/fuse
#cgo linux LDFLAGS: -lfuse
// Use `set CPATH=C:\Program Files (x86)\WinFsp\inc\fuse` on Windows.
// The flag `I/usr/local/include/winfsp` only works on xgo and docker.
#cgo windows CFLAGS: -DFUSE_USE_VERSION=28 -I/usr/local/include/winfsp
#if !(defined(__APPLE__) || defined(__linux__) || defined(_WIN32))
#if !(defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__) || defined(_WIN32))
#error platform not supported
#endif
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#if defined(__APPLE__) || defined(__linux__)
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__)
#include <spawn.h>
#include <sys/mount.h>
Expand Down Expand Up @@ -191,7 +194,7 @@ static PVOID cgofuse_init_winfsp(VOID)
#endif
#if defined(__APPLE__) || defined(__linux__)
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__)
typedef struct stat fuse_stat_t;
typedef struct statvfs fuse_statvfs_t;
typedef struct timespec fuse_timespec_t;
Expand Down Expand Up @@ -257,7 +260,7 @@ static inline void hostAsgnCconninfo(struct fuse_conn_info *conn,
#if defined(__APPLE__)
if (capCaseInsensitive)
FUSE_ENABLE_CASE_INSENSITIVE(conn);
#elif defined(__linux__)
#elif defined(__FreeBSD__) || defined(__linux__)
#elif defined(_WIN32)
#if defined(FSP_FUSE_CAP_STAT_EX)
conn->want |= conn->capable & FSP_FUSE_CAP_STAT_EX;
Expand Down Expand Up @@ -398,15 +401,15 @@ static int _hostGetxattr(char *path, char *name, char *value, size_t size,
static void hostStaticInit(void)
{
#if defined(__APPLE__) || defined(__linux__)
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__)
#elif defined(_WIN32)
InitializeCriticalSection(&cgofuse_lock);
#endif
}
static int hostFuseInit(void)
{
#if defined(__APPLE__) || defined(__linux__)
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__)
return 1;
#elif defined(_WIN32)
return 0 != cgofuse_init_fast(0);
Expand Down Expand Up @@ -502,10 +505,10 @@ static int hostMount(int argc, char *argv[], void *data)
static int hostUnmount(struct fuse *fuse, char *mountpoint)
{
#if defined(__APPLE__)
#if defined(__APPLE__) || defined(__FreeBSD__)
if (0 == mountpoint)
return 0;
// darwin: unmount is available to non-root
// darwin,freebsd: unmount is available to non-root
return 0 == unmount(mountpoint, MNT_FORCE);
#elif defined(__linux__)
if (0 == mountpoint)
Expand Down
2 changes: 1 addition & 1 deletion fuse/host_unix_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// +build darwin linux
// +build darwin freebsd linux

/*
* host_unix_test.go
Expand Down

0 comments on commit 0acc17d

Please sign in to comment.