vendor: switch to using go1.11 modules

This commit is contained in:
Nick Craig-Wood
2018-08-28 16:08:48 +01:00
parent 5c75453aba
commit da1682a30e
6142 changed files with 390 additions and 5155875 deletions
-42
View File
@@ -1,42 +0,0 @@
version: '{build}'
clone_folder: C:\projects\go\src\github.com\billziss-gh\cgofuse
environment:
CPATH: C:\projects\winfsp\inc\fuse
GODEBUG: cgocheck=2
GOPATH: C:\projects\go
PATH: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin;%PATH%
install:
- choco install winfsp --version=1.0.17072 -y
- git clone -q https://github.com/billziss-gh/winfsp.git C:\projects\winfsp
- git -C C:\projects\winfsp checkout -q release/1.2
build_script:
- go install -v ./...
test_script:
- go test -v ./fuse
# hard code fsreg parameters because appveyor does not like percents ("--VolumePrefix=%1 %2")
- C:\projects\winfsp\tools\fsreg.bat gomemfs "C:\projects\go\bin\memfs.exe" "--VolumePrefix=\gomemfs\share M:" "D:P(A;;RPWPLC;;;WD)"
- call "%VS140COMNTOOLS%\..\..\VC\vcvarsall.bat" x64
- devenv C:\projects\winfsp\build\VStudio\winfsp.sln /build "Release|x64"
# test against WinFsp v1.0
- 'net use M: \\gomemfs\share'
- 'M: & cd'
- C:\projects\winfsp\build\VStudio\build\Release\winfsp-tests-x64.exe --external --resilient --share-prefix=\gomemfs\share -create_allocation_test -create_fileattr_test -getfileinfo_name_test -setfileinfo_test -delete_access_test -setsecurity_test -querydir_namelen_test -reparse* -stream*
- 'C: & cd'
- 'net use M: /delete'
# test against WinFsp v1.2 DLL with chflags, setcrtime and setchgtime
# HACK: mixing DLL and FSD versions; do not try this at home
- copy C:\projects\winfsp\build\VStudio\build\Release\winfsp-x64.dll C:\projects\go\bin
- 'net use M: \\gomemfs\share'
- 'M: & cd'
- C:\projects\winfsp\build\VStudio\build\Release\winfsp-tests-x64.exe --external --resilient --share-prefix=\gomemfs\share -create_allocation_test -create_fileattr_test -getfileinfo_name_test -delete_access_test -setsecurity_test -querydir_namelen_test -reparse* -stream*
- 'C: & cd'
- 'net use M: /delete'
-71
View File
@@ -1,71 +0,0 @@
version: 2
jobs:
build:
machine: true
environment:
PROJNAME: github.com/billziss-gh/cgofuse
working_directory: ~/.go_workspace/src/github.com/billziss-gh/cgofuse
steps:
- checkout
# Here we build the billziss/xgo-cgofuse image for testing.
# An alternative would be to just `docker pull billziss/xgo-cgofuse`.
- run:
name: Build xgo-cgofuse image
command: docker build -t billziss/xgo-cgofuse .
- run:
name: Cross-compile cgofuse
command: |
go get -v github.com/karalabe/xgo
xgo \
--image=billziss/xgo-cgofuse \
--targets=darwin/386,darwin/amd64,linux/386,linux/amd64,windows/386,windows/amd64 \
--buildmode=archive \
./fuse
- run:
name: Prepare artifacts
command: |
mkdir -p /tmp/cgofuse.work/src/$PROJNAME/fuse
echo //go:binary-only-package >/tmp/cgofuse.work/src/$PROJNAME/fuse/host.go
echo package fuse >>/tmp/cgofuse.work/src/$PROJNAME/fuse/host.go
echo //go:binary-only-package >/tmp/cgofuse.work/src/$PROJNAME/fuse/fsop.go
echo package fuse >>/tmp/cgofuse.work/src/$PROJNAME/fuse/fsop.go
for f in fuse-*.[al]*; do
d=$(echo "$f" | sed 's/fuse-\([^-.]*\).*-\([^-.]*\)\..*/\1_\2/g')
mkdir -p /tmp/cgofuse.work/pkg/$d/$PROJNAME
cp "$f" /tmp/cgofuse.work/pkg/$d/$PROJNAME/fuse.a
done
mkdir -p /tmp/cgofuse.dist
GIT_DSC=$(git describe --long)
(cd /tmp/cgofuse.work && zip -rv - *) >/tmp/cgofuse.dist/cgofuse-$GIT_DSC.zip
- store_artifacts:
path: /tmp/cgofuse.dist
- deploy:
name: Make github release
command: |
if false && [[ $(git describe --exact-match 2>/dev/null) == v* ]]; then
GIT_TAG=$(git describe --exact-match)
GIT_DSC=$(git describe --long)
go get -v github.com/aktau/github-release
github-release release \
--user "$CIRCLE_PROJECT_USERNAME" \
--repo "$CIRCLE_PROJECT_REPONAME" \
--tag $GIT_TAG \
--pre-release || true
github-release upload \
--user "$CIRCLE_PROJECT_USERNAME" \
--repo "$CIRCLE_PROJECT_REPONAME" \
--tag $GIT_TAG \
--file /tmp/cgofuse.dist/cgofuse-$GIT_DSC.zip \
--name cgofuse-${GIT_TAG:1}.zip \
--replace
fi
-49
View File
@@ -1,49 +0,0 @@
os:
- osx
- linux
language: go
env:
- GODEBUG=cgocheck=2
before_install:
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get -qq update; fi
# FUSE
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install caskroom/cask/osxfuse; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get -qq install libfuse-dev; fi
# secfs.test
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get -qq install libacl1-dev; fi
- mkdir -p /tmp/t/{m,p}
- git clone -q https://github.com/billziss-gh/secfs.test.git /tmp/t/secfs.test
- git -C /tmp/t/secfs.test checkout -q e7edfb503c95998c1b0eb6b3f83ef203b1ed95dc
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then sed -e 's/^fs=.*$/fs="cgofuse"/' -i "" /tmp/t/secfs.test/fstest/fstest/tests/conf; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sed -e 's/^fs=.*$/fs="cgofuse"/' -i"" /tmp/t/secfs.test/fstest/fstest/tests/conf; fi
# the following test started failing on Travis Linux; disabling!
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then mv /tmp/t/secfs.test/fstest/fstest/tests/chown/{,.}00.t; fi
# the following test succeeds on my Mac but fails on Travis OSX; I have no clue why; disabling!
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then mv /tmp/t/secfs.test/fstest/fstest/tests/rmdir/{,.}12.t; fi
- mv /tmp/t/secfs.test/fstest/fstest/tests/{,.}zzz_ResourceFork
- make -C /tmp/t/secfs.test
install:
- go install -v ./...
script:
- go test -v ./fuse
# cgofuse/memfs
- sudo $GOPATH/bin/memfs -o allow_other,default_permissions,use_ino,attr_timeout=0 /tmp/t/m &
- (cd /tmp/t/m && sudo prove -fr /tmp/t/secfs.test/fstest/fstest/tests)
- (cd /tmp/t/m && /tmp/t/secfs.test/tools/bin/fsx -N 10000 test xxxxxx)
- (cd /tmp/t/m && /tmp/t/secfs.test/tools/bin/fsx -e -N 1000 test xxxx)
- sudo umount /tmp/t/m
# cgofuse/passthrough
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then sed -e 's/lchmod)/lchmod) return 1/' -i "" /tmp/t/secfs.test/fstest/fstest/tests/misc.sh; fi
- sudo $GOPATH/bin/passthrough -o allow_other,default_permissions,use_ino,attr_timeout=0 /tmp/t/p /tmp/t/m &
- (cd /tmp/t/m && sudo prove -fr /tmp/t/secfs.test/fstest/fstest/tests)
- (cd /tmp/t/m && /tmp/t/secfs.test/tools/bin/fsx -N 10000 test xxxxxx)
- sudo umount /tmp/t/m
notifications:
email: false
-37
View File
@@ -1,37 +0,0 @@
# Changelog
**v1.1.0**
- `OptParse` function parses FUSE options.
- `fmt.Stringer` and `fmt.GoStringer` implementation for `fuse.Error`.
**v1.0.4**
- Implement BSD `flags`, `chflags`, `setcrtime`, `setchgtime`.
- Improve documentation.
**v1.0.3**
- Windows XP compatibility (eliminate `RegGetValueW`).
**v1.0.2**
- Windows XP compatibility (eliminate slim R/W lock).
**v1.0.1**
- Cross-compilation `Dockerfile`.
- CircleCI integration.
- Do not catch `SIGHUP`.
- Improve documentation.
**v1.0**
- Initial cgofuse release.
- The API is now **FROZEN**. Breaking API changes will receive a major version update (`2.0`). Incremental API changes will receive a minor version update (`1.x`).
-40
View File
@@ -1,40 +0,0 @@
FROM \
karalabe/xgo-latest
MAINTAINER \
Bill Zissimopoulos <billziss at navimatics.com>
# add 32-bit and 64-bit architectures and install 7zip
RUN \
dpkg --add-architecture i386 && \
dpkg --add-architecture amd64 && \
apt-get update && \
apt-get install -y --no-install-recommends p7zip-full
# install OSXFUSE
RUN \
wget -q -O osxfuse.dmg --no-check-certificate \
http://sourceforge.net/projects/osxfuse/files/osxfuse-2.8.3/osxfuse-2.8.3.dmg/download && \
7z e osxfuse.dmg 0.hfs &&\
7z e 0.hfs "FUSE for OS X/Install OSXFUSE 2.8.pkg" && \
7z e "Install OSXFUSE 2.8.pkg" 10.9/OSXFUSECore.pkg/Payload && \
7z e Payload && \
7z x Payload~ -o/tmp && \
cp -R /tmp/usr/local/include/osxfuse /usr/local/include && \
cp /tmp/usr/local/lib/libosxfuse_i64.2.dylib /usr/local/lib/libosxfuse.dylib
# install LIBFUSE
RUN \
apt-get install -y --no-install-recommends libfuse-dev:i386 && \
apt-get install -y --no-install-recommends libfuse-dev:amd64 && \
apt-get download libfuse-dev:i386 && \
dpkg -x libfuse-dev*i386*.deb /
# install WinFsp-FUSE
RUN \
wget -q -O winfsp.zip --no-check-certificate \
https://github.com/billziss-gh/winfsp/archive/release/1.2.zip && \
7z e winfsp.zip 'winfsp-release-1.2/inc/fuse/*' -o/usr/local/include/winfsp
ENV \
OSXCROSS_NO_INCLUDE_PATH_WARNINGS 1
-21
View File
@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2017 Bill Zissimopoulos
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-78
View File
@@ -1,78 +0,0 @@
# Cross-platform FUSE library for Go
[![Travis CI](https://img.shields.io/travis/billziss-gh/cgofuse.svg?label=osx/linux)](https://travis-ci.org/billziss-gh/cgofuse)
[![AppVeyor](https://img.shields.io/appveyor/ci/billziss-gh/cgofuse.svg?label=windows)](https://ci.appveyor.com/project/billziss-gh/cgofuse)
[![CircleCI](https://img.shields.io/circleci/project/github/billziss-gh/cgofuse.svg?label=cross-build)](https://circleci.com/gh/billziss-gh/cgofuse)
[![GoDoc](https://godoc.org/github.com/billziss-gh/cgofuse/fuse?status.svg)](https://godoc.org/github.com/billziss-gh/cgofuse/fuse)
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)).
## How to build
**OSX**
- Prerequisites: [OSXFUSE](https://osxfuse.github.io), [command line tools](https://developer.apple.com/library/content/technotes/tn2339/_index.html)
- 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:
```
> cd cgofuse
> set CPATH=C:\Program Files (x86)\WinFsp\inc\fuse
> go install -v ./fuse ./examples/memfs
```
## How to cross-compile your project using xgo
You can easily cross-compile your project using [xgo](https://github.com/karalabe/xgo) and the [billziss/xgo-cgofuse](https://hub.docker.com/r/billziss/xgo-cgofuse/) docker image.
- Prerequisites: [docker](https://www.docker.com), [xgo](https://github.com/karalabe/xgo)
- Build:
```
$ docker pull billziss/xgo-cgofuse
$ go get -u github.com/karalabe/xgo
$ cd YOUR-PROJECT-THAT-USES-CGOFUSE
$ xgo --image=billziss/xgo-cgofuse \
--targets=darwin/386,darwin/amd64,linux/386,linux/amd64,windows/386,windows/amd64 .
```
## 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`.
The full documentation is available at GoDoc.org: [package fuse](https://godoc.org/github.com/billziss-gh/cgofuse/fuse)
There are currently three example file systems:
- [Hellofs](examples/hellofs/hellofs.go) is an extremely simple file system. Runs on OSX, Linux and Windows.
- [Memfs](examples/memfs/memfs.go) is an in memory file system. Runs on OSX, Linux and Windows.
- [Passthrough](examples/passthrough/passthrough.go) is a file system that passes all operations to the underlying file system. Runs on OSX, Linux.
## How it is tested
Cgofuse is regularly built and tested on [Travis CI](https://travis-ci.org/billziss-gh/cgofuse) and [AppVeyor](https://ci.appveyor.com/project/billziss-gh/cgofuse). The following software is being used to test cgofuse.
**OSX/Linux**
- [fstest](https://github.com/billziss-gh/secfs.test/tree/master/fstest/ntfs-3g-pjd-fstest-8af5670)
- [fsx](https://github.com/billziss-gh/secfs.test/tree/master/fstools/src/fsx)
**Windows**
- [winfsp-tests](https://github.com/billziss-gh/winfsp/tree/master/tst/winfsp-tests)
## Contributors
- Bill Zissimopoulos \<billziss at navimatics.com>
- Nick Craig-Wood \<nick at craig-wood.com>
-79
View File
@@ -1,79 +0,0 @@
/*
* hellofs.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 (
"os"
"github.com/billziss-gh/cgofuse/fuse"
)
const (
filename = "hello"
contents = "hello, world\n"
)
type Hellofs struct {
fuse.FileSystemBase
}
func (self *Hellofs) Open(path string, flags int) (errc int, fh uint64) {
switch path {
case "/" + filename:
return 0, 0
default:
return -fuse.ENOENT, ^uint64(0)
}
}
func (self *Hellofs) Getattr(path string, stat *fuse.Stat_t, fh uint64) (errc int) {
switch path {
case "/":
stat.Mode = fuse.S_IFDIR | 0555
return 0
case "/" + filename:
stat.Mode = fuse.S_IFREG | 0444
stat.Size = int64(len(contents))
return 0
default:
return -fuse.ENOENT
}
}
func (self *Hellofs) Read(path string, buff []byte, ofst int64, fh uint64) (n int) {
endofst := ofst + int64(len(buff))
if endofst > int64(len(contents)) {
endofst = int64(len(contents))
}
if endofst < ofst {
return 0
}
n = copy(buff, contents[ofst:endofst])
return
}
func (self *Hellofs) Readdir(path string,
fill func(name string, stat *fuse.Stat_t, ofst int64) bool,
ofst int64,
fh uint64) (errc int) {
fill(".", nil, 0)
fill("..", nil, 0)
fill(filename, nil, 0)
return 0
}
func main() {
hellofs := &Hellofs{}
host := fuse.NewFileSystemHost(hellofs)
host.Mount("", os.Args[1:])
}
-586
View File
@@ -1,586 +0,0 @@
/*
* memfs.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 (
"fmt"
"os"
"strings"
"sync"
"github.com/billziss-gh/cgofuse/examples/shared"
"github.com/billziss-gh/cgofuse/fuse"
)
func trace(vals ...interface{}) func(vals ...interface{}) {
uid, gid, _ := fuse.Getcontext()
return shared.Trace(1, fmt.Sprintf("[uid=%v,gid=%v]", uid, gid), vals...)
}
func split(path string) []string {
return strings.Split(path, "/")
}
func resize(slice []byte, size int64, zeroinit bool) []byte {
const allocunit = 64 * 1024
allocsize := (size + allocunit - 1) / allocunit * allocunit
if cap(slice) != int(allocsize) {
var newslice []byte
{
defer func() {
if r := recover(); nil != r {
panic(fuse.Error(-fuse.ENOSPC))
}
}()
newslice = make([]byte, size, allocsize)
}
copy(newslice, slice)
slice = newslice
} else if zeroinit {
i := len(slice)
slice = slice[:size]
for ; len(slice) > i; i++ {
slice[i] = 0
}
}
return slice
}
type node_t struct {
stat fuse.Stat_t
xatr map[string][]byte
chld map[string]*node_t
data []byte
opencnt int
}
func newNode(dev uint64, ino uint64, mode uint32, uid uint32, gid uint32) *node_t {
tmsp := fuse.Now()
self := node_t{
fuse.Stat_t{
Dev: dev,
Ino: ino,
Mode: mode,
Nlink: 1,
Uid: uid,
Gid: gid,
Atim: tmsp,
Mtim: tmsp,
Ctim: tmsp,
Birthtim: tmsp,
Flags: 0,
},
nil,
nil,
nil,
0}
if fuse.S_IFDIR == self.stat.Mode&fuse.S_IFMT {
self.chld = map[string]*node_t{}
}
return &self
}
type Memfs struct {
fuse.FileSystemBase
lock sync.Mutex
ino uint64
root *node_t
openmap map[uint64]*node_t
}
func (self *Memfs) Mknod(path string, mode uint32, dev uint64) (errc int) {
defer trace(path, mode, dev)(&errc)
defer self.synchronize()()
return self.makeNode(path, mode, dev, nil)
}
func (self *Memfs) Mkdir(path string, mode uint32) (errc int) {
defer trace(path, mode)(&errc)
defer self.synchronize()()
return self.makeNode(path, fuse.S_IFDIR|(mode&07777), 0, nil)
}
func (self *Memfs) Unlink(path string) (errc int) {
defer trace(path)(&errc)
defer self.synchronize()()
return self.removeNode(path, false)
}
func (self *Memfs) Rmdir(path string) (errc int) {
defer trace(path)(&errc)
defer self.synchronize()()
return self.removeNode(path, true)
}
func (self *Memfs) Link(oldpath string, newpath string) (errc int) {
defer trace(oldpath, newpath)(&errc)
defer self.synchronize()()
_, _, oldnode := self.lookupNode(oldpath, nil)
if nil == oldnode {
return -fuse.ENOENT
}
newprnt, newname, newnode := self.lookupNode(newpath, nil)
if nil == newprnt {
return -fuse.ENOENT
}
if nil != newnode {
return -fuse.EEXIST
}
oldnode.stat.Nlink++
newprnt.chld[newname] = oldnode
tmsp := fuse.Now()
oldnode.stat.Ctim = tmsp
newprnt.stat.Ctim = tmsp
newprnt.stat.Mtim = tmsp
return 0
}
func (self *Memfs) Symlink(target string, newpath string) (errc int) {
defer trace(target, newpath)(&errc)
defer self.synchronize()()
return self.makeNode(newpath, fuse.S_IFLNK|00777, 0, []byte(target))
}
func (self *Memfs) Readlink(path string) (errc int, target string) {
defer trace(path)(&errc, &target)
defer self.synchronize()()
_, _, node := self.lookupNode(path, nil)
if nil == node {
return -fuse.ENOENT, ""
}
if fuse.S_IFLNK != node.stat.Mode&fuse.S_IFMT {
return -fuse.EINVAL, ""
}
return 0, string(node.data)
}
func (self *Memfs) Rename(oldpath string, newpath string) (errc int) {
defer trace(oldpath, newpath)(&errc)
defer self.synchronize()()
oldprnt, oldname, oldnode := self.lookupNode(oldpath, nil)
if nil == oldnode {
return -fuse.ENOENT
}
newprnt, newname, newnode := self.lookupNode(newpath, oldnode)
if nil == newprnt {
return -fuse.ENOENT
}
if "" == newname {
// guard against directory loop creation
return -fuse.EINVAL
}
if oldprnt == newprnt && oldname == newname {
return 0
}
if nil != newnode {
errc = self.removeNode(newpath, fuse.S_IFDIR == oldnode.stat.Mode&fuse.S_IFMT)
if 0 != errc {
return errc
}
}
delete(oldprnt.chld, oldname)
newprnt.chld[newname] = oldnode
return 0
}
func (self *Memfs) Chmod(path string, mode uint32) (errc int) {
defer trace(path, mode)(&errc)
defer self.synchronize()()
_, _, node := self.lookupNode(path, nil)
if nil == node {
return -fuse.ENOENT
}
node.stat.Mode = (node.stat.Mode & fuse.S_IFMT) | mode&07777
node.stat.Ctim = fuse.Now()
return 0
}
func (self *Memfs) Chown(path string, uid uint32, gid uint32) (errc int) {
defer trace(path, uid, gid)(&errc)
defer self.synchronize()()
_, _, node := self.lookupNode(path, nil)
if nil == node {
return -fuse.ENOENT
}
if ^uint32(0) != uid {
node.stat.Uid = uid
}
if ^uint32(0) != gid {
node.stat.Gid = gid
}
node.stat.Ctim = fuse.Now()
return 0
}
func (self *Memfs) Utimens(path string, tmsp []fuse.Timespec) (errc int) {
defer trace(path, tmsp)(&errc)
defer self.synchronize()()
_, _, node := self.lookupNode(path, nil)
if nil == node {
return -fuse.ENOENT
}
node.stat.Ctim = fuse.Now()
if nil == tmsp {
tmsp0 := node.stat.Ctim
tmsa := [2]fuse.Timespec{tmsp0, tmsp0}
tmsp = tmsa[:]
}
node.stat.Atim = tmsp[0]
node.stat.Mtim = tmsp[1]
return 0
}
func (self *Memfs) Open(path string, flags int) (errc int, fh uint64) {
defer trace(path, flags)(&errc, &fh)
defer self.synchronize()()
return self.openNode(path, false)
}
func (self *Memfs) Getattr(path string, stat *fuse.Stat_t, fh uint64) (errc int) {
defer trace(path, fh)(&errc, stat)
defer self.synchronize()()
node := self.getNode(path, fh)
if nil == node {
return -fuse.ENOENT
}
*stat = node.stat
return 0
}
func (self *Memfs) Truncate(path string, size int64, fh uint64) (errc int) {
defer trace(path, size, fh)(&errc)
defer self.synchronize()()
node := self.getNode(path, fh)
if nil == node {
return -fuse.ENOENT
}
node.data = resize(node.data, size, true)
node.stat.Size = size
tmsp := fuse.Now()
node.stat.Ctim = tmsp
node.stat.Mtim = tmsp
return 0
}
func (self *Memfs) Read(path string, buff []byte, ofst int64, fh uint64) (n int) {
defer trace(path, buff, ofst, fh)(&n)
defer self.synchronize()()
node := self.getNode(path, fh)
if nil == node {
return -fuse.ENOENT
}
endofst := ofst + int64(len(buff))
if endofst > node.stat.Size {
endofst = node.stat.Size
}
if endofst < ofst {
return 0
}
n = copy(buff, node.data[ofst:endofst])
node.stat.Atim = fuse.Now()
return
}
func (self *Memfs) Write(path string, buff []byte, ofst int64, fh uint64) (n int) {
defer trace(path, buff, ofst, fh)(&n)
defer self.synchronize()()
node := self.getNode(path, fh)
if nil == node {
return -fuse.ENOENT
}
endofst := ofst + int64(len(buff))
if endofst > node.stat.Size {
node.data = resize(node.data, endofst, true)
node.stat.Size = endofst
}
n = copy(node.data[ofst:endofst], buff)
tmsp := fuse.Now()
node.stat.Ctim = tmsp
node.stat.Mtim = tmsp
return
}
func (self *Memfs) Release(path string, fh uint64) (errc int) {
defer trace(path, fh)(&errc)
defer self.synchronize()()
return self.closeNode(fh)
}
func (self *Memfs) Opendir(path string) (errc int, fh uint64) {
defer trace(path)(&errc, &fh)
defer self.synchronize()()
return self.openNode(path, true)
}
func (self *Memfs) Readdir(path string,
fill func(name string, stat *fuse.Stat_t, ofst int64) bool,
ofst int64,
fh uint64) (errc int) {
defer trace(path, fill, ofst, fh)(&errc)
defer self.synchronize()()
node := self.openmap[fh]
fill(".", &node.stat, 0)
fill("..", nil, 0)
for name, chld := range node.chld {
if !fill(name, &chld.stat, 0) {
break
}
}
return 0
}
func (self *Memfs) Releasedir(path string, fh uint64) (errc int) {
defer trace(path, fh)(&errc)
defer self.synchronize()()
return self.closeNode(fh)
}
func (self *Memfs) Setxattr(path string, name string, value []byte, flags int) (errc int) {
defer trace(path, name, value, flags)(&errc)
defer self.synchronize()()
_, _, node := self.lookupNode(path, nil)
if nil == node {
return -fuse.ENOENT
}
if "com.apple.ResourceFork" == name {
return -fuse.ENOTSUP
}
if fuse.XATTR_CREATE == flags {
if _, ok := node.xatr[name]; ok {
return -fuse.EEXIST
}
} else if fuse.XATTR_REPLACE == flags {
if _, ok := node.xatr[name]; !ok {
return -fuse.ENOATTR
}
}
xatr := make([]byte, len(value))
copy(xatr, value)
if nil == node.xatr {
node.xatr = map[string][]byte{}
}
node.xatr[name] = xatr
return 0
}
func (self *Memfs) Getxattr(path string, name string) (errc int, xatr []byte) {
defer trace(path, name)(&errc, &xatr)
defer self.synchronize()()
_, _, node := self.lookupNode(path, nil)
if nil == node {
return -fuse.ENOENT, nil
}
if "com.apple.ResourceFork" == name {
return -fuse.ENOTSUP, nil
}
xatr, ok := node.xatr[name]
if !ok {
return -fuse.ENOATTR, nil
}
return 0, xatr
}
func (self *Memfs) Removexattr(path string, name string) (errc int) {
defer trace(path, name)(&errc)
defer self.synchronize()()
_, _, node := self.lookupNode(path, nil)
if nil == node {
return -fuse.ENOENT
}
if "com.apple.ResourceFork" == name {
return -fuse.ENOTSUP
}
if _, ok := node.xatr[name]; !ok {
return -fuse.ENOATTR
}
delete(node.xatr, name)
return 0
}
func (self *Memfs) Listxattr(path string, fill func(name string) bool) (errc int) {
defer trace(path, fill)(&errc)
defer self.synchronize()()
_, _, node := self.lookupNode(path, nil)
if nil == node {
return -fuse.ENOENT
}
for name := range node.xatr {
if !fill(name) {
return -fuse.ERANGE
}
}
return 0
}
func (self *Memfs) Chflags(path string, flags uint32) (errc int) {
defer trace(path, flags)(&errc)
defer self.synchronize()()
_, _, node := self.lookupNode(path, nil)
if nil == node {
return -fuse.ENOENT
}
node.stat.Flags = flags
node.stat.Ctim = fuse.Now()
return 0
}
func (self *Memfs) Setcrtime(path string, tmsp fuse.Timespec) (errc int) {
defer trace(path, tmsp)(&errc)
defer self.synchronize()()
_, _, node := self.lookupNode(path, nil)
if nil == node {
return -fuse.ENOENT
}
node.stat.Birthtim = tmsp
node.stat.Ctim = fuse.Now()
return 0
}
func (self *Memfs) Setchgtime(path string, tmsp fuse.Timespec) (errc int) {
defer trace(path, tmsp)(&errc)
defer self.synchronize()()
_, _, node := self.lookupNode(path, nil)
if nil == node {
return -fuse.ENOENT
}
node.stat.Ctim = tmsp
return 0
}
func (self *Memfs) lookupNode(path string, ancestor *node_t) (prnt *node_t, name string, node *node_t) {
prnt = self.root
name = ""
node = self.root
for _, c := range split(path) {
if "" != c {
if 255 < len(c) {
panic(fuse.Error(-fuse.ENAMETOOLONG))
}
prnt, name = node, c
node = node.chld[c]
if nil != ancestor && node == ancestor {
name = "" // special case loop condition
return
}
}
}
return
}
func (self *Memfs) makeNode(path string, mode uint32, dev uint64, data []byte) int {
prnt, name, node := self.lookupNode(path, nil)
if nil == prnt {
return -fuse.ENOENT
}
if nil != node {
return -fuse.EEXIST
}
self.ino++
uid, gid, _ := fuse.Getcontext()
node = newNode(dev, self.ino, mode, uid, gid)
if nil != data {
node.data = make([]byte, len(data))
node.stat.Size = int64(len(data))
copy(node.data, data)
}
prnt.chld[name] = node
prnt.stat.Ctim = node.stat.Ctim
prnt.stat.Mtim = node.stat.Ctim
return 0
}
func (self *Memfs) removeNode(path string, dir bool) int {
prnt, name, node := self.lookupNode(path, nil)
if nil == node {
return -fuse.ENOENT
}
if !dir && fuse.S_IFDIR == node.stat.Mode&fuse.S_IFMT {
return -fuse.EISDIR
}
if dir && fuse.S_IFDIR != node.stat.Mode&fuse.S_IFMT {
return -fuse.ENOTDIR
}
if 0 < len(node.chld) {
return -fuse.ENOTEMPTY
}
node.stat.Nlink--
delete(prnt.chld, name)
tmsp := fuse.Now()
node.stat.Ctim = tmsp
prnt.stat.Ctim = tmsp
prnt.stat.Mtim = tmsp
return 0
}
func (self *Memfs) openNode(path string, dir bool) (int, uint64) {
_, _, node := self.lookupNode(path, nil)
if nil == node {
return -fuse.ENOENT, ^uint64(0)
}
if !dir && fuse.S_IFDIR == node.stat.Mode&fuse.S_IFMT {
return -fuse.EISDIR, ^uint64(0)
}
if dir && fuse.S_IFDIR != node.stat.Mode&fuse.S_IFMT {
return -fuse.ENOTDIR, ^uint64(0)
}
node.opencnt++
if 1 == node.opencnt {
self.openmap[node.stat.Ino] = node
}
return 0, node.stat.Ino
}
func (self *Memfs) closeNode(fh uint64) int {
node := self.openmap[fh]
node.opencnt--
if 0 == node.opencnt {
delete(self.openmap, node.stat.Ino)
}
return 0
}
func (self *Memfs) getNode(path string, fh uint64) *node_t {
if ^uint64(0) == fh {
_, _, node := self.lookupNode(path, nil)
return node
} else {
return self.openmap[fh]
}
}
func (self *Memfs) synchronize() func() {
self.lock.Lock()
return func() {
self.lock.Unlock()
}
}
func NewMemfs() *Memfs {
self := Memfs{}
defer self.synchronize()()
self.ino++
self.root = newNode(0, self.ino, fuse.S_IFDIR|00777, 0, 0)
self.openmap = map[uint64]*node_t{}
return &self
}
var _ fuse.FileSystemChflags = (*Memfs)(nil)
var _ fuse.FileSystemSetcrtime = (*Memfs)(nil)
var _ fuse.FileSystemSetchgtime = (*Memfs)(nil)
func main() {
memfs := NewMemfs()
host := fuse.NewFileSystemHost(memfs)
host.SetCapReaddirPlus(true)
host.Mount("", os.Args[1:])
}
@@ -1,268 +0,0 @@
// +build darwin linux
/*
* passthrough.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 (
"fmt"
"os"
"path/filepath"
"syscall"
"github.com/billziss-gh/cgofuse/examples/shared"
"github.com/billziss-gh/cgofuse/fuse"
)
func trace(vals ...interface{}) func(vals ...interface{}) {
uid, gid, _ := fuse.Getcontext()
return shared.Trace(1, fmt.Sprintf("[uid=%v,gid=%v]", uid, gid), vals...)
}
func errno(err error) int {
if nil != err {
return -int(err.(syscall.Errno))
} else {
return 0
}
}
var (
_host *fuse.FileSystemHost
)
type Ptfs struct {
fuse.FileSystemBase
root string
}
func (self *Ptfs) Init() {
defer trace()()
e := syscall.Chdir(self.root)
if nil == e {
self.root = "./"
}
}
func (self *Ptfs) Statfs(path string, stat *fuse.Statfs_t) (errc int) {
defer trace(path)(&errc, stat)
path = filepath.Join(self.root, path)
stgo := syscall.Statfs_t{}
errc = errno(syscall.Statfs(path, &stgo))
copyFusestatfsFromGostatfs(stat, &stgo)
return
}
func (self *Ptfs) Mknod(path string, mode uint32, dev uint64) (errc int) {
defer trace(path, mode, dev)(&errc)
defer setuidgid()()
path = filepath.Join(self.root, path)
return errno(syscall.Mknod(path, mode, int(dev)))
}
func (self *Ptfs) Mkdir(path string, mode uint32) (errc int) {
defer trace(path, mode)(&errc)
defer setuidgid()()
path = filepath.Join(self.root, path)
return errno(syscall.Mkdir(path, mode))
}
func (self *Ptfs) Unlink(path string) (errc int) {
defer trace(path)(&errc)
path = filepath.Join(self.root, path)
return errno(syscall.Unlink(path))
}
func (self *Ptfs) Rmdir(path string) (errc int) {
defer trace(path)(&errc)
path = filepath.Join(self.root, path)
return errno(syscall.Rmdir(path))
}
func (self *Ptfs) Link(oldpath string, newpath string) (errc int) {
defer trace(oldpath, newpath)(&errc)
defer setuidgid()()
oldpath = filepath.Join(self.root, oldpath)
newpath = filepath.Join(self.root, newpath)
return errno(syscall.Link(oldpath, newpath))
}
func (self *Ptfs) Symlink(target string, newpath string) (errc int) {
defer trace(target, newpath)(&errc)
defer setuidgid()()
newpath = filepath.Join(self.root, newpath)
return errno(syscall.Symlink(target, newpath))
}
func (self *Ptfs) Readlink(path string) (errc int, target string) {
defer trace(path)(&errc, &target)
path = filepath.Join(self.root, path)
buff := [1024]byte{}
n, e := syscall.Readlink(path, buff[:])
if nil != e {
return errno(e), ""
}
return 0, string(buff[:n])
}
func (self *Ptfs) Rename(oldpath string, newpath string) (errc int) {
defer trace(oldpath, newpath)(&errc)
defer setuidgid()()
oldpath = filepath.Join(self.root, oldpath)
newpath = filepath.Join(self.root, newpath)
return errno(syscall.Rename(oldpath, newpath))
}
func (self *Ptfs) Chmod(path string, mode uint32) (errc int) {
defer trace(path, mode)(&errc)
path = filepath.Join(self.root, path)
return errno(syscall.Chmod(path, mode))
}
func (self *Ptfs) Chown(path string, uid uint32, gid uint32) (errc int) {
defer trace(path, uid, gid)(&errc)
path = filepath.Join(self.root, path)
return errno(syscall.Lchown(path, int(uid), int(gid)))
}
func (self *Ptfs) Utimens(path string, tmsp1 []fuse.Timespec) (errc int) {
defer trace(path, tmsp1)(&errc)
path = filepath.Join(self.root, path)
tmsp := [2]syscall.Timespec{}
tmsp[0].Sec, tmsp[0].Nsec = tmsp1[0].Sec, tmsp1[0].Nsec
tmsp[1].Sec, tmsp[1].Nsec = tmsp1[1].Sec, tmsp1[1].Nsec
return errno(syscall.UtimesNano(path, tmsp[:]))
}
func (self *Ptfs) Create(path string, flags int, mode uint32) (errc int, fh uint64) {
defer trace(path, flags, mode)(&errc, &fh)
defer setuidgid()()
return self.open(path, flags, mode)
}
func (self *Ptfs) Open(path string, flags int) (errc int, fh uint64) {
defer trace(path, flags)(&errc, &fh)
return self.open(path, flags, 0)
}
func (self *Ptfs) open(path string, flags int, mode uint32) (errc int, fh uint64) {
path = filepath.Join(self.root, path)
f, e := syscall.Open(path, flags, mode)
if nil != e {
return errno(e), ^uint64(0)
}
return 0, uint64(f)
}
func (self *Ptfs) Getattr(path string, stat *fuse.Stat_t, fh uint64) (errc int) {
defer trace(path, fh)(&errc, stat)
stgo := syscall.Stat_t{}
if ^uint64(0) == fh {
path = filepath.Join(self.root, path)
errc = errno(syscall.Lstat(path, &stgo))
} else {
errc = errno(syscall.Fstat(int(fh), &stgo))
}
copyFusestatFromGostat(stat, &stgo)
return
}
func (self *Ptfs) Truncate(path string, size int64, fh uint64) (errc int) {
defer trace(path, size, fh)(&errc)
if ^uint64(0) == fh {
path = filepath.Join(self.root, path)
errc = errno(syscall.Truncate(path, size))
} else {
errc = errno(syscall.Ftruncate(int(fh), size))
}
return
}
func (self *Ptfs) Read(path string, buff []byte, ofst int64, fh uint64) (n int) {
defer trace(path, buff, ofst, fh)(&n)
n, e := syscall.Pread(int(fh), buff, ofst)
if nil != e {
return errno(e)
}
return n
}
func (self *Ptfs) Write(path string, buff []byte, ofst int64, fh uint64) (n int) {
defer trace(path, buff, ofst, fh)(&n)
n, e := syscall.Pwrite(int(fh), buff, ofst)
if nil != e {
return errno(e)
}
return n
}
func (self *Ptfs) Release(path string, fh uint64) (errc int) {
defer trace(path, fh)(&errc)
return errno(syscall.Close(int(fh)))
}
func (self *Ptfs) Fsync(path string, datasync bool, fh uint64) (errc int) {
defer trace(path, datasync, fh)(&errc)
return errno(syscall.Fsync(int(fh)))
}
func (self *Ptfs) Opendir(path string) (errc int, fh uint64) {
defer trace(path)(&errc, &fh)
path = filepath.Join(self.root, path)
f, e := syscall.Open(path, syscall.O_RDONLY|syscall.O_DIRECTORY, 0)
if nil != e {
return errno(e), ^uint64(0)
}
return 0, uint64(f)
}
func (self *Ptfs) Readdir(path string,
fill func(name string, stat *fuse.Stat_t, ofst int64) bool,
ofst int64,
fh uint64) (errc int) {
defer trace(path, fill, ofst, fh)(&errc)
path = filepath.Join(self.root, path)
file, e := os.Open(path)
if nil != e {
return errno(e)
}
defer file.Close()
nams, e := file.Readdirnames(0)
if nil != e {
return errno(e)
}
nams = append([]string{".", ".."}, nams...)
for _, name := range nams {
if !fill(name, nil, 0) {
break
}
}
return 0
}
func (self *Ptfs) Releasedir(path string, fh uint64) (errc int) {
defer trace(path, fh)(&errc)
return errno(syscall.Close(int(fh)))
}
func main() {
syscall.Umask(0)
ptfs := Ptfs{}
args := os.Args
if 3 <= len(args) && '-' != args[len(args)-2][0] && '-' != args[len(args)-1][0] {
ptfs.root, _ = filepath.Abs(args[len(args)-2])
args = append(args[:len(args)-2], args[len(args)-1])
}
_host = fuse.NewFileSystemHost(&ptfs)
_host.Mount("", args[1:])
}
@@ -1,68 +0,0 @@
// +build darwin
/*
* struct_darwin.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
}
@@ -1,67 +0,0 @@
// +build linux
/*
* struct_linux.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.Setregid(-1, int(gid))
syscall.Setreuid(-1, int(uid))
return func() {
syscall.Setreuid(-1, int(euid))
syscall.Setregid(-1, int(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.Atim.Sec, src.Atim.Nsec
dst.Mtim.Sec, dst.Mtim.Nsec = src.Mtim.Sec, src.Mtim.Nsec
dst.Ctim.Sec, dst.Ctim.Nsec = src.Ctim.Sec, src.Ctim.Nsec
dst.Blksize = int64(src.Blksize)
dst.Blocks = int64(src.Blocks)
}
-115
View File
@@ -1,115 +0,0 @@
/*
* trace.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 shared
import (
"fmt"
"log"
"os"
"path/filepath"
"runtime"
)
var (
TracePattern = os.Getenv("CGOFUSE_TRACE")
)
func traceJoin(deref bool, vals []interface{}) string {
rslt := ""
for _, v := range vals {
if deref {
switch i := v.(type) {
case *bool:
rslt += fmt.Sprintf(", %#v", *i)
case *int:
rslt += fmt.Sprintf(", %#v", *i)
case *int8:
rslt += fmt.Sprintf(", %#v", *i)
case *int16:
rslt += fmt.Sprintf(", %#v", *i)
case *int32:
rslt += fmt.Sprintf(", %#v", *i)
case *int64:
rslt += fmt.Sprintf(", %#v", *i)
case *uint:
rslt += fmt.Sprintf(", %#v", *i)
case *uint8:
rslt += fmt.Sprintf(", %#v", *i)
case *uint16:
rslt += fmt.Sprintf(", %#v", *i)
case *uint32:
rslt += fmt.Sprintf(", %#v", *i)
case *uint64:
rslt += fmt.Sprintf(", %#v", *i)
case *uintptr:
rslt += fmt.Sprintf(", %#v", *i)
case *float32:
rslt += fmt.Sprintf(", %#v", *i)
case *float64:
rslt += fmt.Sprintf(", %#v", *i)
case *complex64:
rslt += fmt.Sprintf(", %#v", *i)
case *complex128:
rslt += fmt.Sprintf(", %#v", *i)
case *string:
rslt += fmt.Sprintf(", %#v", *i)
default:
rslt += fmt.Sprintf(", %#v", v)
}
} else {
rslt += fmt.Sprintf(", %#v", v)
}
}
if len(rslt) > 0 {
rslt = rslt[2:]
}
return rslt
}
func Trace(skip int, prfx string, vals ...interface{}) func(vals ...interface{}) {
if "" == TracePattern {
return func(vals ...interface{}) {
}
}
pc, _, _, ok := runtime.Caller(skip + 1)
name := "<UNKNOWN>"
if ok {
fn := runtime.FuncForPC(pc)
name = fn.Name()
if m, _ := filepath.Match(TracePattern, name); !m {
return func(vals ...interface{}) {
}
}
}
if "" != prfx {
prfx = prfx + ": "
}
args := traceJoin(false, vals)
return func(vals ...interface{}) {
form := "%v%v(%v) = %v"
rslt := ""
rcvr := recover()
if nil != rcvr {
rslt = fmt.Sprintf("!PANIC:%v", rcvr)
} else {
if len(vals) != 1 {
form = "%v%v(%v) = (%v)"
}
rslt = traceJoin(true, vals)
}
log.Printf(form, prfx, name, args, rslt)
if nil != rcvr {
panic(rcvr)
}
}
}
-109
View File
@@ -1,109 +0,0 @@
/*
* host_test.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 fuse
import (
"io/ioutil"
"os"
"path/filepath"
"runtime"
"testing"
"time"
)
type testfs struct {
FileSystemBase
init, dstr int
}
func (self *testfs) Init() {
self.init++
}
func (self *testfs) Destroy() {
self.dstr++
}
func (self *testfs) Getattr(path string, stat *Stat_t, fh uint64) (errc int) {
switch path {
case "/":
stat.Mode = S_IFDIR | 0555
return 0
default:
return -ENOENT
}
}
func (self *testfs) Readdir(path string,
fill func(name string, stat *Stat_t, ofst int64) bool,
ofst int64,
fh uint64) (errc int) {
fill(".", nil, 0)
fill("..", nil, 0)
return 0
}
func testHost(t *testing.T, unmount bool) {
path, err := ioutil.TempDir("", "test")
if nil != err {
panic(err)
}
defer os.Remove(path)
mntp := filepath.Join(path, "m")
if "windows" != runtime.GOOS {
err = os.Mkdir(mntp, os.FileMode(0755))
if nil != err {
panic(err)
}
defer os.Remove(mntp)
}
done := make(chan bool)
tmch := time.After(3 * time.Second)
tstf := &testfs{}
host := NewFileSystemHost(tstf)
mres := false
ures := false
go func() {
mres = host.Mount(mntp, nil)
done <- true
}()
<-tmch
if unmount {
ures = host.Unmount()
} else {
ures = sendInterrupt()
}
<-done
if !mres {
t.Error("Mount failed")
}
if !ures {
t.Error("Unmount failed")
}
if 1 != tstf.init {
t.Errorf("Init() called %v times; expected 1", tstf.init)
}
if 1 != tstf.dstr {
t.Errorf("Destroy() called %v times; expected 1", tstf.dstr)
}
}
func TestUnmount(t *testing.T) {
testHost(t, true)
}
func TestSignal(t *testing.T) {
if "windows" != runtime.GOOS {
testHost(t, false)
}
}
-23
View File
@@ -1,23 +0,0 @@
// +build darwin linux
/*
* host_unix_test.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 fuse
import (
"syscall"
)
func sendInterrupt() bool {
return nil == syscall.Kill(syscall.Getpid(), syscall.SIGINT)
}
-27
View File
@@ -1,27 +0,0 @@
// +build windows
/*
* host_windows_test.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 fuse
import (
"os"
"syscall"
)
func sendInterrupt() bool {
dll := syscall.MustLoadDLL("kernel32")
prc := dll.MustFindProc("GenerateConsoleCtrlEvent")
r, _, _ := prc.Call(syscall.CTRL_BREAK_EVENT, uintptr(os.Getpid()))
return 0 != r
}
-192
View File
@@ -1,192 +0,0 @@
/*
* opt_test.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 fuse
import (
"reflect"
"testing"
)
func TestOptParse(t *testing.T) {
args := []string{
"-s",
"--long=LONG",
"--d=-42",
"--d8=-8",
"--d16=-16",
"--d32=-32",
"--d64=-64",
"--u=-42",
"--u8=-8",
"--u16=-16",
"--u32=-32",
"--u64=-64",
"--uptr=42",
"--X=abc",
"--O=0777",
"--I=0xabc",
"--S=string",
"--V=value",
"-o",
"n1=v1",
"-o",
"n2=v2",
"--",
"-o",
"n3=v3",
"arg1",
"arg2",
}
expargs := []string{
"-o",
"n1=v1,n2=v2",
"-s",
"--long=LONG",
"--d=-42",
"--d8=-8",
"--d16=-16",
"--d32=-32",
"--d64=-64",
"--u=-42",
"--u8=-8",
"--u16=-16",
"--u32=-32",
"--u64=-64",
"--uptr=42",
"--X=abc",
"--O=0777",
"--I=0xabc",
"--S=string",
"--V=value",
"--",
"-o",
"n3=v3",
"arg1",
"arg2",
}
expargs2 := []string{
"-o",
"n3=v3",
"arg1",
"arg2",
}
var dummy bool
outargs, err := OptParse(args, "DUMMY", &dummy)
if nil != err {
t.Error(err)
}
if !reflect.DeepEqual(expargs, outargs) {
t.Error()
}
outargs, err = OptParse(args, "")
if nil != err {
t.Error(err)
}
if !reflect.DeepEqual(expargs2, outargs) {
t.Error()
}
var (
d int
d8 int8
d16 int16
d32 int32
d64 int64
u uint
u8 uint8
u16 uint16
u32 uint32
u64 uint64
uptr uintptr
)
outargs, err = OptParse(args,
"--d=%d --d8=%d --d16=%d --d32=%d --d64=%d --u=%d --u8=%d --u16=%d --u32=%d --u64=%d "+
"--uptr=%d",
&d, &d8, &d16, &d32, &d64, &u, &u8, &u16, &u32, &u64, &uptr)
if nil != err {
t.Error(err)
}
if -42 != d || -8 != d8 || -16 != d16 || -32 != d32 || -64 != d64 {
t.Error()
}
if uint(-42&0xffffffff) != u ||
uint8(-8&0xff) != u8 ||
uint16(-16&0xffff) != u16 ||
uint32(-32&0xffffffff) != u32 ||
uint64(-64&0xffffffffffffffff) != u64 ||
uintptr(42) != uptr {
t.Error()
}
d = 0
d8 = 0
d16 = 0
d32 = 0
d64 = 0
u = 0
u8 = 0
u16 = 0
u32 = 0
u64 = 0
uptr = 0
outargs, err = OptParse(args,
"--d --d8 --d16 --d32 --d64 --u --u8 --u16 --u32 --u64 "+
"--uptr",
&d, &d8, &d16, &d32, &d64, &u, &u8, &u16, &u32, &u64, &uptr)
if nil != err {
t.Error(err)
}
if -42 != d || -8 != d8 || -16 != d16 || -32 != d32 || -64 != d64 {
t.Error()
}
if uint(-42&0xffffffff) != u ||
uint8(-8&0xff) != u8 ||
uint16(-16&0xffff) != u16 ||
uint32(-32&0xffffffff) != u32 ||
uint64(-64&0xffffffffffffffff) != u64 ||
uintptr(42) != uptr {
t.Error()
}
var (
s bool
longbool bool
long string
Xbool bool
X uint
O uint
Ibool bool
I uint
S string
V string
)
outargs, err = OptParse(args, "-s --long= --long --X=%x --X=%x --O=%o --I=%v --I --S=%s --V",
&s, &longbool, &long, &Xbool, &X, &O, &Ibool, &I, &S, &V)
if nil != err {
t.Error()
}
if !s || !longbool || "LONG" != long ||
!Xbool || 0xabc != X || 0777 != O || !Ibool || 0xabc != I ||
"string" != S || "value" != V {
t.Error()
}
}