Этот коммит содержится в:
Christopher Speller
2016-05-12 23:56:07 -04:00
родитель 84d2482ddb
Коммит 38ee83e45b
1099 изменённых файлов: 277713 добавлений и 4019 удалений

20
vendor/github.com/mattermost/rsc/fuse/debug.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,20 @@
// Copyright 2012 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.
// FUSE service loop, for servers that wish to use it.
package fuse
import (
"runtime"
)
func stack() string {
buf := make([]byte, 1024)
return string(buf[:runtime.Stack(buf, false)])
}
var Debugf = nop
func nop(string, ...interface{}) {}

1650
vendor/github.com/mattermost/rsc/fuse/fuse.go сгенерированный поставляемый Обычный файл

Разница между файлами не показана из-за своего большого размера Загрузить разницу

539
vendor/github.com/mattermost/rsc/fuse/fuse_kernel.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,539 @@
// 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.
// Derived from FUSE's fuse_kernel.h
/*
This file defines the kernel interface of FUSE
Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
This -- and only this -- header file may also be distributed under
the terms of the BSD Licence as follows:
Copyright (C) 2001-2007 Miklos Szeredi. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
package fuse
import (
"fmt"
"unsafe"
)
// Version is the FUSE version implemented by the package.
const Version = "7.8"
const (
kernelVersion = 7
kernelMinorVersion = 8
rootID = 1
)
type kstatfs struct {
Blocks uint64
Bfree uint64
Bavail uint64
Files uint64
Ffree uint64
Bsize uint32
Namelen uint32
Frsize uint32
Padding uint32
Spare [6]uint32
}
type fileLock struct {
Start uint64
End uint64
Type uint32
Pid uint32
}
// The SetattrValid are bit flags describing which fields in the SetattrRequest
// are included in the change.
type SetattrValid uint32
const (
SetattrMode SetattrValid = 1 << 0
SetattrUid SetattrValid = 1 << 1
SetattrGid SetattrValid = 1 << 2
SetattrSize SetattrValid = 1 << 3
SetattrAtime SetattrValid = 1 << 4
SetattrMtime SetattrValid = 1 << 5
SetattrHandle SetattrValid = 1 << 6 // TODO: What does this mean?
// Linux only(?)
SetattrAtimeNow SetattrValid = 1 << 7
SetattrMtimeNow SetattrValid = 1 << 8
SetattrLockOwner SetattrValid = 1 << 9 // http://www.mail-archive.com/git-commits-head@vger.kernel.org/msg27852.html
// OS X only
SetattrCrtime SetattrValid = 1 << 28
SetattrChgtime SetattrValid = 1 << 29
SetattrBkuptime SetattrValid = 1 << 30
SetattrFlags SetattrValid = 1 << 31
)
func (fl SetattrValid) Mode() bool { return fl&SetattrMode != 0 }
func (fl SetattrValid) Uid() bool { return fl&SetattrUid != 0 }
func (fl SetattrValid) Gid() bool { return fl&SetattrGid != 0 }
func (fl SetattrValid) Size() bool { return fl&SetattrSize != 0 }
func (fl SetattrValid) Atime() bool { return fl&SetattrAtime != 0 }
func (fl SetattrValid) Mtime() bool { return fl&SetattrMtime != 0 }
func (fl SetattrValid) Handle() bool { return fl&SetattrHandle != 0 }
func (fl SetattrValid) Crtime() bool { return fl&SetattrCrtime != 0 }
func (fl SetattrValid) Chgtime() bool { return fl&SetattrChgtime != 0 }
func (fl SetattrValid) Bkuptime() bool { return fl&SetattrBkuptime != 0 }
func (fl SetattrValid) Flags() bool { return fl&SetattrFlags != 0 }
func (fl SetattrValid) String() string {
return flagString(uint32(fl), setattrValidNames)
}
var setattrValidNames = []flagName{
{uint32(SetattrMode), "SetattrMode"},
{uint32(SetattrUid), "SetattrUid"},
{uint32(SetattrGid), "SetattrGid"},
{uint32(SetattrSize), "SetattrSize"},
{uint32(SetattrAtime), "SetattrAtime"},
{uint32(SetattrMtime), "SetattrMtime"},
{uint32(SetattrHandle), "SetattrHandle"},
{uint32(SetattrCrtime), "SetattrCrtime"},
{uint32(SetattrChgtime), "SetattrChgtime"},
{uint32(SetattrBkuptime), "SetattrBkuptime"},
{uint32(SetattrFlags), "SetattrFlags"},
}
// The OpenFlags are returned in the OpenResponse.
type OpenFlags uint32
const (
OpenDirectIO OpenFlags = 1 << 0 // bypass page cache for this open file
OpenKeepCache OpenFlags = 1 << 1 // don't invalidate the data cache on open
OpenNonSeekable OpenFlags = 1 << 2 // (Linux?)
OpenPurgeAttr OpenFlags = 1 << 30 // OS X
OpenPurgeUBC OpenFlags = 1 << 31 // OS X
)
func (fl OpenFlags) String() string {
return flagString(uint32(fl), openFlagNames)
}
var openFlagNames = []flagName{
{uint32(OpenDirectIO), "OpenDirectIO"},
{uint32(OpenKeepCache), "OpenKeepCache"},
{uint32(OpenPurgeAttr), "OpenPurgeAttr"},
{uint32(OpenPurgeUBC), "OpenPurgeUBC"},
}
// The InitFlags are used in the Init exchange.
type InitFlags uint32
const (
InitAsyncRead InitFlags = 1 << 0
InitPosixLocks InitFlags = 1 << 1
InitCaseSensitive InitFlags = 1 << 29 // OS X only
InitVolRename InitFlags = 1 << 30 // OS X only
InitXtimes InitFlags = 1 << 31 // OS X only
)
type flagName struct {
bit uint32
name string
}
var initFlagNames = []flagName{
{uint32(InitAsyncRead), "InitAsyncRead"},
{uint32(InitPosixLocks), "InitPosixLocks"},
{uint32(InitCaseSensitive), "InitCaseSensitive"},
{uint32(InitVolRename), "InitVolRename"},
{uint32(InitXtimes), "InitXtimes"},
}
func (fl InitFlags) String() string {
return flagString(uint32(fl), initFlagNames)
}
func flagString(f uint32, names []flagName) string {
var s string
if f == 0 {
return "0"
}
for _, n := range names {
if f&n.bit != 0 {
s += "+" + n.name
f &^= n.bit
}
}
if f != 0 {
s += fmt.Sprintf("%+#x", f)
}
return s[1:]
}
// The ReleaseFlags are used in the Release exchange.
type ReleaseFlags uint32
const (
ReleaseFlush ReleaseFlags = 1 << 0
)
func (fl ReleaseFlags) String() string {
return flagString(uint32(fl), releaseFlagNames)
}
var releaseFlagNames = []flagName{
{uint32(ReleaseFlush), "ReleaseFlush"},
}
// Opcodes
const (
opLookup = 1
opForget = 2 // no reply
opGetattr = 3
opSetattr = 4
opReadlink = 5
opSymlink = 6
opMknod = 8
opMkdir = 9
opUnlink = 10
opRmdir = 11
opRename = 12
opLink = 13
opOpen = 14
opRead = 15
opWrite = 16
opStatfs = 17
opRelease = 18
opFsync = 20
opSetxattr = 21
opGetxattr = 22
opListxattr = 23
opRemovexattr = 24
opFlush = 25
opInit = 26
opOpendir = 27
opReaddir = 28
opReleasedir = 29
opFsyncdir = 30
opGetlk = 31
opSetlk = 32
opSetlkw = 33
opAccess = 34
opCreate = 35
opInterrupt = 36
opBmap = 37
opDestroy = 38
opIoctl = 39 // Linux?
opPoll = 40 // Linux?
// OS X
opSetvolname = 61
opGetxtimes = 62
opExchange = 63
)
// The read buffer is required to be at least 8k but may be much larger
const minReadBuffer = 8192
type entryOut struct {
outHeader
Nodeid uint64 // Inode ID
Generation uint64 // Inode generation
EntryValid uint64 // Cache timeout for the name
AttrValid uint64 // Cache timeout for the attributes
EntryValidNsec uint32
AttrValidNsec uint32
Attr attr
}
type forgetIn struct {
Nlookup uint64
}
type attrOut struct {
outHeader
AttrValid uint64 // Cache timeout for the attributes
AttrValidNsec uint32
Dummy uint32
Attr attr
}
// OS X
type getxtimesOut struct {
outHeader
Bkuptime uint64
Crtime uint64
BkuptimeNsec uint32
CrtimeNsec uint32
}
type mknodIn struct {
Mode uint32
Rdev uint32
// "filename\x00" follows.
}
type mkdirIn struct {
Mode uint32
Padding uint32
// filename follows
}
type renameIn struct {
Newdir uint64
// "oldname\x00newname\x00" follows
}
// OS X
type exchangeIn struct {
Olddir uint64
Newdir uint64
Options uint64
}
type linkIn struct {
Oldnodeid uint64
}
type setattrInCommon struct {
Valid uint32
Padding uint32
Fh uint64
Size uint64
LockOwner uint64 // unused on OS X?
Atime uint64
Mtime uint64
Unused2 uint64
AtimeNsec uint32
MtimeNsec uint32
Unused3 uint32
Mode uint32
Unused4 uint32
Uid uint32
Gid uint32
Unused5 uint32
}
type openIn struct {
Flags uint32
Mode uint32
}
type openOut struct {
outHeader
Fh uint64
OpenFlags uint32
Padding uint32
}
type createOut struct {
outHeader
Nodeid uint64 // Inode ID
Generation uint64 // Inode generation
EntryValid uint64 // Cache timeout for the name
AttrValid uint64 // Cache timeout for the attributes
EntryValidNsec uint32
AttrValidNsec uint32
Attr attr
Fh uint64
OpenFlags uint32
Padding uint32
}
type releaseIn struct {
Fh uint64
Flags uint32
ReleaseFlags uint32
LockOwner uint32
}
type flushIn struct {
Fh uint64
FlushFlags uint32
Padding uint32
LockOwner uint64
}
type readIn struct {
Fh uint64
Offset uint64
Size uint32
Padding uint32
}
type writeIn struct {
Fh uint64
Offset uint64
Size uint32
WriteFlags uint32
}
type writeOut struct {
outHeader
Size uint32
Padding uint32
}
// The WriteFlags are returned in the WriteResponse.
type WriteFlags uint32
func (fl WriteFlags) String() string {
return flagString(uint32(fl), writeFlagNames)
}
var writeFlagNames = []flagName{}
const compatStatfsSize = 48
type statfsOut struct {
outHeader
St kstatfs
}
type fsyncIn struct {
Fh uint64
FsyncFlags uint32
Padding uint32
}
type setxattrIn struct {
Size uint32
Flags uint32
}
type setxattrInOSX struct {
Size uint32
Flags uint32
// OS X only
Position uint32
Padding uint32
}
type getxattrIn struct {
Size uint32
Padding uint32
}
type getxattrInOSX struct {
Size uint32
Padding uint32
// OS X only
Position uint32
Padding2 uint32
}
type getxattrOut struct {
outHeader
Size uint32
Padding uint32
}
type lkIn struct {
Fh uint64
Owner uint64
Lk fileLock
}
type lkOut struct {
outHeader
Lk fileLock
}
type accessIn struct {
Mask uint32
Padding uint32
}
type initIn struct {
Major uint32
Minor uint32
MaxReadahead uint32
Flags uint32
}
const initInSize = int(unsafe.Sizeof(initIn{}))
type initOut struct {
outHeader
Major uint32
Minor uint32
MaxReadahead uint32
Flags uint32
Unused uint32
MaxWrite uint32
}
type interruptIn struct {
Unique uint64
}
type bmapIn struct {
Block uint64
BlockSize uint32
Padding uint32
}
type bmapOut struct {
outHeader
Block uint64
}
type inHeader struct {
Len uint32
Opcode uint32
Unique uint64
Nodeid uint64
Uid uint32
Gid uint32
Pid uint32
Padding uint32
}
const inHeaderSize = int(unsafe.Sizeof(inHeader{}))
type outHeader struct {
Len uint32
Error int32
Unique uint64
}
type dirent struct {
Ino uint64
Off uint64
Namelen uint32
Type uint32
Name [0]byte
}
const direntSize = 8 + 8 + 4 + 4

58
vendor/github.com/mattermost/rsc/fuse/fuse_kernel_darwin.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,58 @@
package fuse
import (
"time"
)
type attr struct {
Ino uint64
Size uint64
Blocks uint64
Atime uint64
Mtime uint64
Ctime uint64
Crtime_ uint64 // OS X only
AtimeNsec uint32
MtimeNsec uint32
CtimeNsec uint32
CrtimeNsec uint32 // OS X only
Mode uint32
Nlink uint32
Uid uint32
Gid uint32
Rdev uint32
Flags_ uint32 // OS X only; see chflags(2)
}
func (a *attr) SetCrtime(s uint64, ns uint32) {
a.Crtime_, a.CrtimeNsec = s, ns
}
func (a *attr) SetFlags(f uint32) {
a.Flags_ = f
}
type setattrIn struct {
setattrInCommon
// OS X only
Bkuptime_ uint64
Chgtime_ uint64
Crtime uint64
BkuptimeNsec uint32
ChgtimeNsec uint32
CrtimeNsec uint32
Flags_ uint32 // see chflags(2)
}
func (in *setattrIn) BkupTime() time.Time {
return time.Unix(int64(in.Bkuptime_), int64(in.BkuptimeNsec))
}
func (in *setattrIn) Chgtime() time.Time {
return time.Unix(int64(in.Chgtime_), int64(in.ChgtimeNsec))
}
func (in *setattrIn) Flags() uint32 {
return in.Flags_
}

50
vendor/github.com/mattermost/rsc/fuse/fuse_kernel_linux.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,50 @@
package fuse
import "time"
type attr struct {
Ino uint64
Size uint64
Blocks uint64
Atime uint64
Mtime uint64
Ctime uint64
AtimeNsec uint32
MtimeNsec uint32
CtimeNsec uint32
Mode uint32
Nlink uint32
Uid uint32
Gid uint32
Rdev uint32
// Blksize uint32 // Only in protocol 7.9
// padding_ uint32 // Only in protocol 7.9
}
func (a *attr) Crtime() time.Time {
return time.Time{}
}
func (a *attr) SetCrtime(s uint64, ns uint32) {
// Ignored on Linux.
}
func (a *attr) SetFlags(f uint32) {
// Ignored on Linux.
}
type setattrIn struct {
setattrInCommon
}
func (in *setattrIn) BkupTime() time.Time {
return time.Time{}
}
func (in *setattrIn) Chgtime() time.Time {
return time.Time{}
}
func (in *setattrIn) Flags() uint32 {
return 0
}

1
vendor/github.com/mattermost/rsc/fuse/fuse_kernel_std.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1 @@
package fuse

594
vendor/github.com/mattermost/rsc/fuse/fuse_test.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,594 @@
// Copyright 2012 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.
package fuse
import (
"flag"
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
"runtime"
"syscall"
"testing"
"time"
)
var fuseRun = flag.String("fuserun", "", "which fuse test to run. runs all if empty.")
// umount tries its best to unmount dir.
func umount(dir string) {
err := exec.Command("umount", dir).Run()
if err != nil && runtime.GOOS == "linux" {
exec.Command("/bin/fusermount", "-u", dir).Run()
}
}
func TestFuse(t *testing.T) {
Debugf = log.Printf
dir, err := ioutil.TempDir("", "fusetest")
if err != nil {
t.Fatal(err)
}
os.MkdirAll(dir, 0777)
c, err := Mount(dir)
if err != nil {
t.Fatal(err)
}
defer umount(dir)
go func() {
err := c.Serve(testFS{})
if err != nil {
fmt.Printf("SERVE ERROR: %v\n", err)
}
}()
waitForMount(t, dir)
for _, tt := range fuseTests {
if *fuseRun == "" || *fuseRun == tt.name {
t.Logf("running %T", tt.node)
tt.node.test(dir+"/"+tt.name, t)
}
}
}
func waitForMount(t *testing.T, dir string) {
// Filename to wait for in dir:
probeEntry := *fuseRun
if probeEntry == "" {
probeEntry = fuseTests[0].name
}
for tries := 0; tries < 100; tries++ {
_, err := os.Stat(dir + "/" + probeEntry)
if err == nil {
return
}
time.Sleep(10 * time.Millisecond)
}
t.Fatalf("mount did not work")
}
var fuseTests = []struct {
name string
node interface {
Node
test(string, *testing.T)
}
}{
{"readAll", readAll{}},
{"readAll1", &readAll1{}},
{"write", &write{}},
{"writeAll", &writeAll{}},
{"writeAll2", &writeAll2{}},
{"release", &release{}},
{"mkdir1", &mkdir1{}},
{"create1", &create1{}},
{"create2", &create2{}},
{"symlink1", &symlink1{}},
{"link1", &link1{}},
{"rename1", &rename1{}},
{"mknod1", &mknod1{}},
}
// TO TEST:
// Statfs
// Lookup(*LookupRequest, *LookupResponse)
// Getattr(*GetattrRequest, *GetattrResponse)
// Attr with explicit inode
// Setattr(*SetattrRequest, *SetattrResponse)
// Access(*AccessRequest)
// Open(*OpenRequest, *OpenResponse)
// Getxattr, Setxattr, Listxattr, Removexattr
// Write(*WriteRequest, *WriteResponse)
// Flush(*FlushRequest, *FlushResponse)
// Test Read calling ReadAll.
type readAll struct{ file }
const hi = "hello, world"
func (readAll) ReadAll(intr Intr) ([]byte, Error) {
return []byte(hi), nil
}
func (readAll) test(path string, t *testing.T) {
data, err := ioutil.ReadFile(path)
if err != nil {
t.Errorf("readAll: %v", err)
return
}
if string(data) != hi {
t.Errorf("readAll = %q, want %q", data, hi)
}
}
// Test Read.
type readAll1 struct{ file }
func (readAll1) Read(req *ReadRequest, resp *ReadResponse, intr Intr) Error {
HandleRead(req, resp, []byte(hi))
return nil
}
func (readAll1) test(path string, t *testing.T) {
readAll{}.test(path, t)
}
// Test Write calling basic Write, with an fsync thrown in too.
type write struct {
file
data []byte
gotfsync bool
}
func (w *write) Write(req *WriteRequest, resp *WriteResponse, intr Intr) Error {
w.data = append(w.data, req.Data...)
resp.Size = len(req.Data)
return nil
}
func (w *write) Fsync(r *FsyncRequest, intr Intr) Error {
w.gotfsync = true
return nil
}
func (w *write) test(path string, t *testing.T) {
log.Printf("pre-write Create")
f, err := os.Create(path)
if err != nil {
t.Fatalf("Create: %v", err)
}
log.Printf("pre-write Write")
n, err := f.Write([]byte(hi))
if err != nil {
t.Fatalf("Write: %v", err)
}
if n != len(hi) {
t.Fatalf("short write; n=%d; hi=%d", n, len(hi))
}
err = syscall.Fsync(int(f.Fd()))
if err != nil {
t.Fatalf("Fsync = %v", err)
}
if !w.gotfsync {
t.Errorf("never received expected fsync call")
}
log.Printf("pre-write Close")
err = f.Close()
if err != nil {
t.Fatalf("Close: %v", err)
}
log.Printf("post-write Close")
if string(w.data) != hi {
t.Errorf("writeAll = %q, want %q", w.data, hi)
}
}
// Test Write calling WriteAll.
type writeAll struct {
file
data []byte
gotfsync bool
}
func (w *writeAll) Fsync(r *FsyncRequest, intr Intr) Error {
w.gotfsync = true
return nil
}
func (w *writeAll) WriteAll(data []byte, intr Intr) Error {
w.data = data
return nil
}
func (w *writeAll) test(path string, t *testing.T) {
err := ioutil.WriteFile(path, []byte(hi), 0666)
if err != nil {
t.Fatalf("WriteFile: %v", err)
return
}
if string(w.data) != hi {
t.Errorf("writeAll = %q, want %q", w.data, hi)
}
}
// Test Write calling Setattr+Write+Flush.
type writeAll2 struct {
file
data []byte
setattr bool
flush bool
}
func (w *writeAll2) Setattr(req *SetattrRequest, resp *SetattrResponse, intr Intr) Error {
w.setattr = true
return nil
}
func (w *writeAll2) Flush(req *FlushRequest, intr Intr) Error {
w.flush = true
return nil
}
func (w *writeAll2) Write(req *WriteRequest, resp *WriteResponse, intr Intr) Error {
w.data = append(w.data, req.Data...)
resp.Size = len(req.Data)
return nil
}
func (w *writeAll2) test(path string, t *testing.T) {
err := ioutil.WriteFile(path, []byte(hi), 0666)
if err != nil {
t.Errorf("WriteFile: %v", err)
return
}
if !w.setattr || string(w.data) != hi || !w.flush {
t.Errorf("writeAll = %v, %q, %v, want %v, %q, %v", w.setattr, string(w.data), w.flush, true, hi, true)
}
}
// Test Mkdir.
type mkdir1 struct {
dir
name string
}
func (f *mkdir1) Mkdir(req *MkdirRequest, intr Intr) (Node, Error) {
f.name = req.Name
return &mkdir1{}, nil
}
func (f *mkdir1) test(path string, t *testing.T) {
f.name = ""
err := os.Mkdir(path+"/foo", 0777)
if err != nil {
t.Error(err)
return
}
if f.name != "foo" {
t.Error(err)
return
}
}
// Test Create (and fsync)
type create1 struct {
dir
name string
f *writeAll
}
func (f *create1) Create(req *CreateRequest, resp *CreateResponse, intr Intr) (Node, Handle, Error) {
f.name = req.Name
f.f = &writeAll{}
return f.f, f.f, nil
}
func (f *create1) test(path string, t *testing.T) {
f.name = ""
ff, err := os.Create(path + "/foo")
if err != nil {
t.Errorf("create1 WriteFile: %v", err)
return
}
err = syscall.Fsync(int(ff.Fd()))
if err != nil {
t.Fatalf("Fsync = %v", err)
}
if !f.f.gotfsync {
t.Errorf("never received expected fsync call")
}
ff.Close()
if f.name != "foo" {
t.Errorf("create1 name=%q want foo", f.name)
}
}
// Test Create + WriteAll + Remove
type create2 struct {
dir
name string
f *writeAll
fooExists bool
}
func (f *create2) Create(req *CreateRequest, resp *CreateResponse, intr Intr) (Node, Handle, Error) {
f.name = req.Name
f.f = &writeAll{}
return f.f, f.f, nil
}
func (f *create2) Lookup(name string, intr Intr) (Node, Error) {
if f.fooExists && name == "foo" {
return file{}, nil
}
return nil, ENOENT
}
func (f *create2) Remove(r *RemoveRequest, intr Intr) Error {
if f.fooExists && r.Name == "foo" && !r.Dir {
f.fooExists = false
return nil
}
return ENOENT
}
func (f *create2) test(path string, t *testing.T) {
f.name = ""
err := ioutil.WriteFile(path+"/foo", []byte(hi), 0666)
if err != nil {
t.Fatalf("create2 WriteFile: %v", err)
}
if string(f.f.data) != hi {
t.Fatalf("create2 writeAll = %q, want %q", f.f.data, hi)
}
f.fooExists = true
log.Printf("pre-Remove")
err = os.Remove(path + "/foo")
if err != nil {
t.Fatalf("Remove: %v", err)
}
err = os.Remove(path + "/foo")
if err == nil {
t.Fatalf("second Remove = nil; want some error")
}
}
// Test symlink + readlink
type symlink1 struct {
dir
newName, target string
}
func (f *symlink1) Symlink(req *SymlinkRequest, intr Intr) (Node, Error) {
f.newName = req.NewName
f.target = req.Target
return symlink{target: req.Target}, nil
}
func (f *symlink1) test(path string, t *testing.T) {
const target = "/some-target"
err := os.Symlink(target, path+"/symlink.file")
if err != nil {
t.Errorf("os.Symlink: %v", err)
return
}
if f.newName != "symlink.file" {
t.Errorf("symlink newName = %q; want %q", f.newName, "symlink.file")
}
if f.target != target {
t.Errorf("symlink target = %q; want %q", f.target, target)
}
gotName, err := os.Readlink(path + "/symlink.file")
if err != nil {
t.Errorf("os.Readlink: %v", err)
return
}
if gotName != target {
t.Errorf("os.Readlink = %q; want %q", gotName, target)
}
}
// Test link
type link1 struct {
dir
newName string
}
func (f *link1) Lookup(name string, intr Intr) (Node, Error) {
if name == "old" {
return file{}, nil
}
return nil, ENOENT
}
func (f *link1) Link(r *LinkRequest, old Node, intr Intr) (Node, Error) {
f.newName = r.NewName
return file{}, nil
}
func (f *link1) test(path string, t *testing.T) {
err := os.Link(path+"/old", path+"/new")
if err != nil {
t.Fatalf("Link: %v", err)
}
if f.newName != "new" {
t.Fatalf("saw Link for newName %q; want %q", f.newName, "new")
}
}
// Test Rename
type rename1 struct {
dir
renames int
}
func (f *rename1) Lookup(name string, intr Intr) (Node, Error) {
if name == "old" {
return file{}, nil
}
return nil, ENOENT
}
func (f *rename1) Rename(r *RenameRequest, newDir Node, intr Intr) Error {
if r.OldName == "old" && r.NewName == "new" && newDir == f {
f.renames++
return nil
}
return EIO
}
func (f *rename1) test(path string, t *testing.T) {
err := os.Rename(path+"/old", path+"/new")
if err != nil {
t.Fatalf("Rename: %v", err)
}
if f.renames != 1 {
t.Fatalf("expected rename didn't happen")
}
err = os.Rename(path+"/old2", path+"/new2")
if err == nil {
t.Fatal("expected error on second Rename; got nil")
}
}
// Test Release.
type release struct {
file
did bool
}
func (r *release) Release(*ReleaseRequest, Intr) Error {
r.did = true
return nil
}
func (r *release) test(path string, t *testing.T) {
r.did = false
f, err := os.Open(path)
if err != nil {
t.Error(err)
return
}
f.Close()
time.Sleep(1 * time.Second)
if !r.did {
t.Error("Close did not Release")
}
}
// Test mknod
type mknod1 struct {
dir
gotr *MknodRequest
}
func (f *mknod1) Mknod(r *MknodRequest, intr Intr) (Node, Error) {
f.gotr = r
return fifo{}, nil
}
func (f *mknod1) test(path string, t *testing.T) {
if os.Getuid() != 0 {
t.Logf("skipping unless root")
return
}
defer syscall.Umask(syscall.Umask(0))
err := syscall.Mknod(path+"/node", syscall.S_IFIFO|0666, 123)
if err != nil {
t.Fatalf("Mknod: %v", err)
}
if f.gotr == nil {
t.Fatalf("no recorded MknodRequest")
}
if g, e := f.gotr.Name, "node"; g != e {
t.Errorf("got Name = %q; want %q", g, e)
}
if g, e := f.gotr.Rdev, uint32(123); g != e {
if runtime.GOOS == "linux" {
// Linux fuse doesn't echo back the rdev if the node
// isn't a device (we're using a FIFO here, as that
// bit is portable.)
} else {
t.Errorf("got Rdev = %v; want %v", g, e)
}
}
if g, e := f.gotr.Mode, os.FileMode(os.ModeNamedPipe|0666); g != e {
t.Errorf("got Mode = %v; want %v", g, e)
}
t.Logf("Got request: %#v", f.gotr)
}
type file struct{}
type dir struct{}
type fifo struct{}
type symlink struct {
target string
}
func (f file) Attr() Attr { return Attr{Mode: 0666} }
func (f dir) Attr() Attr { return Attr{Mode: os.ModeDir | 0777} }
func (f fifo) Attr() Attr { return Attr{Mode: os.ModeNamedPipe | 0666} }
func (f symlink) Attr() Attr { return Attr{Mode: os.ModeSymlink | 0666} }
func (f symlink) Readlink(*ReadlinkRequest, Intr) (string, Error) {
return f.target, nil
}
type testFS struct{}
func (testFS) Root() (Node, Error) {
return testFS{}, nil
}
func (testFS) Attr() Attr {
return Attr{Mode: os.ModeDir | 0555}
}
func (testFS) Lookup(name string, intr Intr) (Node, Error) {
for _, tt := range fuseTests {
if tt.name == name {
return tt.node, nil
}
}
return nil, ENOENT
}
func (testFS) ReadDir(intr Intr) ([]Dirent, Error) {
var dirs []Dirent
for _, tt := range fuseTests {
if *fuseRun == "" || *fuseRun == tt.name {
log.Printf("Readdir; adding %q", tt.name)
dirs = append(dirs, Dirent{Name: tt.name})
}
}
return dirs, nil
}

62
vendor/github.com/mattermost/rsc/fuse/hellofs/hello.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,62 @@
// Copyright 2012 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.
// Hellofs implements a simple "hello world" file system.
package main
import (
"log"
"os"
"github.com/mattermost/rsc/fuse"
)
func main() {
c, err := fuse.Mount("/mnt/hellofs")
if err != nil {
log.Fatal(err)
}
c.Serve(FS{})
}
// FS implements the hello world file system.
type FS struct{}
func (FS) Root() (fuse.Node, fuse.Error) {
return Dir{}, nil
}
// Dir implements both Node and Handle for the root directory.
type Dir struct{}
func (Dir) Attr() fuse.Attr {
return fuse.Attr{Mode: os.ModeDir | 0555}
}
func (Dir) Lookup(name string, intr fuse.Intr) (fuse.Node, fuse.Error) {
if name == "hello" {
return File{}, nil
}
return nil, fuse.ENOENT
}
var dirDirs = []fuse.Dirent{
{Inode: 2, Name: "hello", Type: 0},
}
func (Dir) ReadDir(intr fuse.Intr) ([]fuse.Dirent, fuse.Error) {
return dirDirs, nil
}
// File implements both Node and Handle for the hello file.
type File struct{}
func (File) Attr() fuse.Attr {
return fuse.Attr{Mode: 0444}
}
func (File) ReadAll(intr fuse.Intr) ([]byte, fuse.Error) {
return []byte("hello, world\n"), nil
}

122
vendor/github.com/mattermost/rsc/fuse/mount_darwin.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,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
}

67
vendor/github.com/mattermost/rsc/fuse/mount_linux.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,67 @@
// Copyright 2012 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.
package fuse
import (
"fmt"
"net"
"os"
"os/exec"
"syscall"
)
func mount(dir string) (fusefd int, errmsg string) {
fds, err := syscall.Socketpair(syscall.AF_FILE, syscall.SOCK_STREAM, 0)
if err != nil {
return -1, fmt.Sprintf("socketpair error: %v", err)
}
defer syscall.Close(fds[0])
defer syscall.Close(fds[1])
cmd := exec.Command("/bin/fusermount", "--", dir)
cmd.Env = append(os.Environ(), "_FUSE_COMMFD=3")
writeFile := os.NewFile(uintptr(fds[0]), "fusermount-child-writes")
defer writeFile.Close()
cmd.ExtraFiles = []*os.File{writeFile}
out, err := cmd.CombinedOutput()
if len(out) > 0 || err != nil {
return -1, fmt.Sprintf("fusermount: %q, %v", out, err)
}
readFile := os.NewFile(uintptr(fds[1]), "fusermount-parent-reads")
defer readFile.Close()
c, err := net.FileConn(readFile)
if err != nil {
return -1, fmt.Sprintf("FileConn from fusermount socket: %v", err)
}
defer c.Close()
uc, ok := c.(*net.UnixConn)
if !ok {
return -1, fmt.Sprintf("unexpected FileConn type; expected UnixConn, got %T", c)
}
buf := make([]byte, 32) // expect 1 byte
oob := make([]byte, 32) // expect 24 bytes
_, oobn, _, _, err := uc.ReadMsgUnix(buf, oob)
scms, err := syscall.ParseSocketControlMessage(oob[:oobn])
if err != nil {
return -1, fmt.Sprintf("ParseSocketControlMessage: %v", err)
}
if len(scms) != 1 {
return -1, fmt.Sprintf("expected 1 SocketControlMessage; got scms = %#v", scms)
}
scm := scms[0]
gotFds, err := syscall.ParseUnixRights(&scm)
if err != nil {
return -1, fmt.Sprintf("syscall.ParseUnixRights: %v", err)
}
if len(gotFds) != 1 {
return -1, fmt.Sprintf("wanted 1 fd; got %#v", gotFds)
}
return gotFds[0], ""
}

1022
vendor/github.com/mattermost/rsc/fuse/serve.go сгенерированный поставляемый Обычный файл

Разница между файлами не показана из-за своего большого размера Загрузить разницу

93
vendor/github.com/mattermost/rsc/fuse/tree.go сгенерированный поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,93 @@
// Copyright 2012 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.
// FUSE directory tree, for servers that wish to use it with the service loop.
package fuse
import (
"os"
pathpkg "path"
"strings"
)
// A Tree implements a basic directory tree for FUSE.
type Tree struct {
tree
}
func (t *Tree) Root() (Node, Error) {
return &t.tree, nil
}
// Add adds the path to the tree, resolving to the given node.
// If path or a prefix of path has already been added to the tree,
// Add panics.
func (t *Tree) Add(path string, node Node) {
path = pathpkg.Clean("/" + path)[1:]
elems := strings.Split(path, "/")
dir := Node(&t.tree)
for i, elem := range elems {
dt, ok := dir.(*tree)
if !ok {
panic("fuse: Tree.Add for " + strings.Join(elems[:i], "/") + " and " + path)
}
n := dt.lookup(elem)
if n != nil {
if i+1 == len(elems) {
panic("fuse: Tree.Add for " + path + " conflicts with " + elem)
}
dir = n
} else {
if i+1 == len(elems) {
dt.add(elem, node)
} else {
dir = &tree{}
dt.add(elem, dir)
}
}
}
}
type treeDir struct {
name string
node Node
}
type tree struct {
dir []treeDir
}
func (t *tree) lookup(name string) Node {
for _, d := range t.dir {
if d.name == name {
return d.node
}
}
return nil
}
func (t *tree) add(name string, n Node) {
t.dir = append(t.dir, treeDir{name, n})
}
func (t *tree) Attr() Attr {
return Attr{Mode: os.ModeDir | 0555}
}
func (t *tree) Lookup(name string, intr Intr) (Node, Error) {
n := t.lookup(name)
if n != nil {
return n, nil
}
return nil, ENOENT
}
func (t *tree) ReadDir(intr Intr) ([]Dirent, Error) {
var out []Dirent
for _, d := range t.dir {
out = append(out, Dirent{Name: d.name})
}
return out, nil
}