vendor: update all dependencies
* Update all dependencies * Remove all `[[constraint]]` from Gopkg.toml * Add in the minimum number of `[[override]]` to build * Remove go get of github.com/inconshreveable/mousetrap as it is vendored * Update docs with new policy on constraints
This commit is contained in:
+3
-3
@@ -17,7 +17,7 @@ build_script:
|
||||
- go install -v ./...
|
||||
|
||||
test_script:
|
||||
- go test ./fuse
|
||||
- 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)"
|
||||
@@ -28,7 +28,7 @@ test_script:
|
||||
# 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 -getfileinfo_name_test -setfileinfo_test -delete_access_test -setsecurity_test -reparse* -stream*
|
||||
- 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'
|
||||
|
||||
@@ -37,6 +37,6 @@ test_script:
|
||||
- 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 -getfileinfo_name_test -delete_access_test -setsecurity_test -reparse* -stream*
|
||||
- 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'
|
||||
|
||||
+2
-2
@@ -17,7 +17,7 @@ before_install:
|
||||
- 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 a00c9165646f78ad53d3ec052860384a029683e5
|
||||
- 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!
|
||||
@@ -31,7 +31,7 @@ install:
|
||||
- go install -v ./...
|
||||
|
||||
script:
|
||||
- go test ./fuse
|
||||
- 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)
|
||||
|
||||
+31
@@ -1,5 +1,36 @@
|
||||
# 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.
|
||||
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* errstr.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
|
||||
|
||||
var errorStrings = []struct {
|
||||
errc int
|
||||
errs string
|
||||
}{
|
||||
{E2BIG, "E2BIG"},
|
||||
{EACCES, "EACCES"},
|
||||
{EADDRINUSE, "EADDRINUSE"},
|
||||
{EADDRNOTAVAIL, "EADDRNOTAVAIL"},
|
||||
{EAFNOSUPPORT, "EAFNOSUPPORT"},
|
||||
{EAGAIN, "EAGAIN"},
|
||||
{EALREADY, "EALREADY"},
|
||||
{EBADF, "EBADF"},
|
||||
{EBADMSG, "EBADMSG"},
|
||||
{EBUSY, "EBUSY"},
|
||||
{ECANCELED, "ECANCELED"},
|
||||
{ECHILD, "ECHILD"},
|
||||
{ECONNABORTED, "ECONNABORTED"},
|
||||
{ECONNREFUSED, "ECONNREFUSED"},
|
||||
{ECONNRESET, "ECONNRESET"},
|
||||
{EDEADLK, "EDEADLK"},
|
||||
{EDESTADDRREQ, "EDESTADDRREQ"},
|
||||
{EDOM, "EDOM"},
|
||||
{EEXIST, "EEXIST"},
|
||||
{EFAULT, "EFAULT"},
|
||||
{EFBIG, "EFBIG"},
|
||||
{EHOSTUNREACH, "EHOSTUNREACH"},
|
||||
{EIDRM, "EIDRM"},
|
||||
{EILSEQ, "EILSEQ"},
|
||||
{EINPROGRESS, "EINPROGRESS"},
|
||||
{EINTR, "EINTR"},
|
||||
{EINVAL, "EINVAL"},
|
||||
{EIO, "EIO"},
|
||||
{EISCONN, "EISCONN"},
|
||||
{EISDIR, "EISDIR"},
|
||||
{ELOOP, "ELOOP"},
|
||||
{EMFILE, "EMFILE"},
|
||||
{EMLINK, "EMLINK"},
|
||||
{EMSGSIZE, "EMSGSIZE"},
|
||||
{ENAMETOOLONG, "ENAMETOOLONG"},
|
||||
{ENETDOWN, "ENETDOWN"},
|
||||
{ENETRESET, "ENETRESET"},
|
||||
{ENETUNREACH, "ENETUNREACH"},
|
||||
{ENFILE, "ENFILE"},
|
||||
{ENOATTR, "ENOATTR"},
|
||||
{ENOBUFS, "ENOBUFS"},
|
||||
{ENODATA, "ENODATA"},
|
||||
{ENODEV, "ENODEV"},
|
||||
{ENOENT, "ENOENT"},
|
||||
{ENOEXEC, "ENOEXEC"},
|
||||
{ENOLCK, "ENOLCK"},
|
||||
{ENOLINK, "ENOLINK"},
|
||||
{ENOMEM, "ENOMEM"},
|
||||
{ENOMSG, "ENOMSG"},
|
||||
{ENOPROTOOPT, "ENOPROTOOPT"},
|
||||
{ENOSPC, "ENOSPC"},
|
||||
{ENOSR, "ENOSR"},
|
||||
{ENOSTR, "ENOSTR"},
|
||||
{ENOSYS, "ENOSYS"},
|
||||
{ENOTCONN, "ENOTCONN"},
|
||||
{ENOTDIR, "ENOTDIR"},
|
||||
{ENOTEMPTY, "ENOTEMPTY"},
|
||||
{ENOTRECOVERABLE, "ENOTRECOVERABLE"},
|
||||
{ENOTSOCK, "ENOTSOCK"},
|
||||
{ENOTSUP, "ENOTSUP"},
|
||||
{ENOTTY, "ENOTTY"},
|
||||
{ENXIO, "ENXIO"},
|
||||
{EOPNOTSUPP, "EOPNOTSUPP"},
|
||||
{EOVERFLOW, "EOVERFLOW"},
|
||||
{EOWNERDEAD, "EOWNERDEAD"},
|
||||
{EPERM, "EPERM"},
|
||||
{EPIPE, "EPIPE"},
|
||||
{EPROTO, "EPROTO"},
|
||||
{EPROTONOSUPPORT, "EPROTONOSUPPORT"},
|
||||
{EPROTOTYPE, "EPROTOTYPE"},
|
||||
{ERANGE, "ERANGE"},
|
||||
{EROFS, "EROFS"},
|
||||
{ESPIPE, "ESPIPE"},
|
||||
{ESRCH, "ESRCH"},
|
||||
{ETIME, "ETIME"},
|
||||
{ETIMEDOUT, "ETIMEDOUT"},
|
||||
{ETXTBSY, "ETXTBSY"},
|
||||
{EWOULDBLOCK, "EWOULDBLOCK"},
|
||||
{EXDEV, "EXDEV"},
|
||||
}
|
||||
+28
-2
@@ -144,6 +144,7 @@ package fuse
|
||||
import "C"
|
||||
import (
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -417,7 +418,7 @@ type Lock_t struct {
|
||||
}
|
||||
*/
|
||||
|
||||
// FileSystemInterface is the interface that a user mode interface must implement.
|
||||
// FileSystemInterface is the interface that a user mode file system must implement.
|
||||
//
|
||||
// The file system will receive an Init() call when the file system is created;
|
||||
// the Init() call will happen prior to receiving any other file system calls.
|
||||
@@ -567,8 +568,33 @@ type FileSystemSetchgtime interface {
|
||||
// to the OS.
|
||||
type Error int
|
||||
|
||||
var errorStringMap map[Error]string
|
||||
var errorStringOnce sync.Once
|
||||
|
||||
func (self Error) Error() string {
|
||||
return "fuse.Error(" + strconv.Itoa(int(self)) + ")"
|
||||
errorStringOnce.Do(func() {
|
||||
errorStringMap = make(map[Error]string)
|
||||
for _, i := range errorStrings {
|
||||
errorStringMap[Error(-i.errc)] = i.errs
|
||||
}
|
||||
})
|
||||
|
||||
if 0 <= self {
|
||||
return strconv.Itoa(int(self))
|
||||
} else {
|
||||
if errs, ok := errorStringMap[self]; ok {
|
||||
return "-fuse." + errs
|
||||
}
|
||||
return "fuse.Error(" + strconv.Itoa(int(self)) + ")"
|
||||
}
|
||||
}
|
||||
|
||||
func (self Error) String() string {
|
||||
return self.Error()
|
||||
}
|
||||
|
||||
func (self Error) GoString() string {
|
||||
return self.Error()
|
||||
}
|
||||
|
||||
var _ error = (*Error)(nil)
|
||||
|
||||
+265
@@ -200,10 +200,12 @@ typedef dev_t fuse_dev_t;
|
||||
typedef uid_t fuse_uid_t;
|
||||
typedef gid_t fuse_gid_t;
|
||||
typedef off_t fuse_off_t;
|
||||
typedef unsigned long fuse_opt_offset_t;
|
||||
#elif defined(_WIN32)
|
||||
typedef struct fuse_stat fuse_stat_t;
|
||||
typedef struct fuse_statvfs fuse_statvfs_t;
|
||||
typedef struct fuse_timespec fuse_timespec_t;
|
||||
typedef unsigned int fuse_opt_offset_t;
|
||||
#endif
|
||||
|
||||
extern int hostGetattr(char *path, fuse_stat_t *stbuf);
|
||||
@@ -532,12 +534,32 @@ static int hostUnmount(struct fuse *fuse, char *mountpoint)
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int hostOptParseOptProc(void *opt_data, const char *arg, int key,
|
||||
struct fuse_args *outargs)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
default:
|
||||
return 0;
|
||||
case FUSE_OPT_KEY_NONOPT:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int hostOptParse(struct fuse_args *args, void *data, const struct fuse_opt opts[],
|
||||
bool nonopts)
|
||||
{
|
||||
return fuse_opt_parse(args, data, opts, nonopts ? hostOptParseOptProc : 0);
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"os/signal"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
@@ -1228,6 +1250,249 @@ func Getcontext() (uid uint32, gid uint32, pid int) {
|
||||
return
|
||||
}
|
||||
|
||||
func optNormBool(opt string) string {
|
||||
if i := strings.Index(opt, "=%"); -1 != i {
|
||||
switch opt[i+2:] {
|
||||
case "d", "o", "x", "X":
|
||||
return opt
|
||||
case "v":
|
||||
return opt[:i+1]
|
||||
default:
|
||||
panic("unknown format " + opt[i+1:])
|
||||
}
|
||||
} else {
|
||||
return opt
|
||||
}
|
||||
}
|
||||
|
||||
func optNormInt(opt string, modf string) string {
|
||||
if i := strings.Index(opt, "=%"); -1 != i {
|
||||
switch opt[i+2:] {
|
||||
case "d", "o", "x", "X":
|
||||
return opt[:i+2] + modf + opt[i+2:]
|
||||
case "v":
|
||||
return opt[:i+2] + modf + "i"
|
||||
default:
|
||||
panic("unknown format " + opt[i+1:])
|
||||
}
|
||||
} else if strings.HasSuffix(opt, "=") {
|
||||
return opt + "%" + modf + "i"
|
||||
} else {
|
||||
return opt + "=%" + modf + "i"
|
||||
}
|
||||
}
|
||||
|
||||
func optNormStr(opt string) string {
|
||||
if i := strings.Index(opt, "=%"); -1 != i {
|
||||
switch opt[i+2:] {
|
||||
case "s", "v":
|
||||
return opt[:i+2] + "s"
|
||||
default:
|
||||
panic("unknown format " + opt[i+1:])
|
||||
}
|
||||
} else if strings.HasSuffix(opt, "=") {
|
||||
return opt + "%s"
|
||||
} else {
|
||||
return opt + "=%s"
|
||||
}
|
||||
}
|
||||
|
||||
// OptParse parses the FUSE command line arguments in args as determined by format
|
||||
// and stores the resulting values in vals, which must be pointers. It returns a
|
||||
// list of unparsed arguments or nil if an error happens.
|
||||
//
|
||||
// The format may be empty or non-empty. An empty format is taken as a special
|
||||
// instruction to OptParse to only return all non-option arguments in outargs.
|
||||
//
|
||||
// A non-empty format is a space separated list of acceptable FUSE options. Each
|
||||
// option is matched with a corresponding pointer value in vals. The combination
|
||||
// of the option and the type of the corresponding pointer value, determines how
|
||||
// the option is used. The allowed pointer types are pointer to bool, pointer to
|
||||
// an integer type and pointer to string.
|
||||
//
|
||||
// For pointer to bool types:
|
||||
//
|
||||
// -x Match -x without parameter.
|
||||
// -foo --foo As above for -foo or --foo.
|
||||
// foo Match "-o foo".
|
||||
// -x= -foo= --foo= foo= Match option with parameter.
|
||||
// -x=%VERB ... foo=%VERB Match option with parameter of syntax.
|
||||
// Allowed verbs: d,o,x,X,v
|
||||
// - d,o,x,X: set to true if parameter non-0.
|
||||
// - v: set to true if parameter present.
|
||||
//
|
||||
// The formats -x=, and -x=%v are equivalent.
|
||||
//
|
||||
// For pointer to other types:
|
||||
//
|
||||
// -x Match -x with parameter (-x=PARAM).
|
||||
// -foo --foo As above for -foo or --foo.
|
||||
// foo Match "-o foo=PARAM".
|
||||
// -x= -foo= --foo= foo= Match option with parameter.
|
||||
// -x=%VERB ... foo=%VERB Match option with parameter of syntax.
|
||||
// Allowed verbs for pointer to int types: d,o,x,X,v
|
||||
// Allowed verbs for pointer to string types: s,v
|
||||
//
|
||||
// The formats -x, -x=, and -x=%v are equivalent.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// var f bool
|
||||
// var set_attr_timeout bool
|
||||
// var attr_timeout int
|
||||
// var umask uint32
|
||||
// outargs, err := OptParse(args, "-f attr_timeout= attr_timeout umask=%o",
|
||||
// &f, &set_attr_timeout, &attr_timeout, &umask)
|
||||
//
|
||||
// Will accept a command line of:
|
||||
//
|
||||
// $ program -f -o attr_timeout=42,umask=077
|
||||
//
|
||||
// And will set variables as follows:
|
||||
//
|
||||
// f == true
|
||||
// set_attr_timeout == true
|
||||
// attr_timeout == 42
|
||||
// umask == 077
|
||||
//
|
||||
func OptParse(args []string, format string, vals ...interface{}) (outargs []string, err error) {
|
||||
if 0 == C.hostFuseInit() {
|
||||
panic("cgofuse: cannot find winfsp")
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if r := recover(); nil != r {
|
||||
if s, ok := r.(string); ok {
|
||||
outargs = nil
|
||||
err = errors.New("OptParse: " + s)
|
||||
} else {
|
||||
panic(r)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
var opts []string
|
||||
var nonopts bool
|
||||
if "" == format {
|
||||
opts = make([]string, 0)
|
||||
nonopts = true
|
||||
} else {
|
||||
opts = strings.Split(format, " ")
|
||||
}
|
||||
|
||||
align := int(2 * unsafe.Sizeof(C.size_t(0))) // match malloc alignment (usually 8 or 16)
|
||||
|
||||
fuse_opts := make([]C.struct_fuse_opt, len(opts)+1)
|
||||
for i := 0; len(opts) > i; i++ {
|
||||
switch vals[i].(type) {
|
||||
case *bool:
|
||||
fuse_opts[i].templ = C.CString(optNormBool(opts[i]))
|
||||
case *int:
|
||||
fuse_opts[i].templ = C.CString(optNormInt(opts[i], ""))
|
||||
case *int8:
|
||||
fuse_opts[i].templ = C.CString(optNormInt(opts[i], "hh"))
|
||||
case *int16:
|
||||
fuse_opts[i].templ = C.CString(optNormInt(opts[i], "h"))
|
||||
case *int32:
|
||||
fuse_opts[i].templ = C.CString(optNormInt(opts[i], ""))
|
||||
case *int64:
|
||||
fuse_opts[i].templ = C.CString(optNormInt(opts[i], "ll"))
|
||||
case *uint:
|
||||
fuse_opts[i].templ = C.CString(optNormInt(opts[i], ""))
|
||||
case *uint8:
|
||||
fuse_opts[i].templ = C.CString(optNormInt(opts[i], "hh"))
|
||||
case *uint16:
|
||||
fuse_opts[i].templ = C.CString(optNormInt(opts[i], "h"))
|
||||
case *uint32:
|
||||
fuse_opts[i].templ = C.CString(optNormInt(opts[i], ""))
|
||||
case *uint64:
|
||||
fuse_opts[i].templ = C.CString(optNormInt(opts[i], "ll"))
|
||||
case *uintptr:
|
||||
fuse_opts[i].templ = C.CString(optNormInt(opts[i], "ll"))
|
||||
case *string:
|
||||
fuse_opts[i].templ = C.CString(optNormStr(opts[i]))
|
||||
}
|
||||
defer C.free(unsafe.Pointer(fuse_opts[i].templ))
|
||||
|
||||
// Work around Go pre-1.10 limitation. See golang issue:
|
||||
// https://github.com/golang/go/issues/21809
|
||||
*(*C.fuse_opt_offset_t)(unsafe.Pointer(&fuse_opts[i].offset)) =
|
||||
C.fuse_opt_offset_t(i * align)
|
||||
|
||||
fuse_opts[i].value = 1
|
||||
}
|
||||
|
||||
fuse_args := C.struct_fuse_args{}
|
||||
defer C.fuse_opt_free_args(&fuse_args)
|
||||
argc := 1 + len(args)
|
||||
argp := C.calloc(C.size_t(argc+1), C.size_t(unsafe.Sizeof((*C.char)(nil))))
|
||||
defer C.free(argp)
|
||||
argv := (*[1 << 16]*C.char)(argp)
|
||||
argv[0] = C.CString("<UNKNOWN>")
|
||||
defer C.free(unsafe.Pointer(argv[0]))
|
||||
for i := 0; len(args) > i; i++ {
|
||||
argv[1+i] = C.CString(args[i])
|
||||
defer C.free(unsafe.Pointer(argv[1+i]))
|
||||
}
|
||||
fuse_args.argc = C.int(argc)
|
||||
fuse_args.argv = (**C.char)(&argv[0])
|
||||
|
||||
data := C.calloc(C.size_t(len(opts)), C.size_t(align))
|
||||
defer C.free(data)
|
||||
|
||||
if -1 == C.hostOptParse(&fuse_args, data, &fuse_opts[0], C.bool(nonopts)) {
|
||||
panic("failed")
|
||||
}
|
||||
|
||||
for i := 0; len(opts) > i; i++ {
|
||||
switch v := vals[i].(type) {
|
||||
case *bool:
|
||||
*v = 0 != int(*(*C.int)(unsafe.Pointer(uintptr(data) + uintptr(i*align))))
|
||||
case *int:
|
||||
*v = int(*(*C.int)(unsafe.Pointer(uintptr(data) + uintptr(i*align))))
|
||||
case *int8:
|
||||
*v = int8(*(*C.int8_t)(unsafe.Pointer(uintptr(data) + uintptr(i*align))))
|
||||
case *int16:
|
||||
*v = int16(*(*C.int16_t)(unsafe.Pointer(uintptr(data) + uintptr(i*align))))
|
||||
case *int32:
|
||||
*v = int32(*(*C.int32_t)(unsafe.Pointer(uintptr(data) + uintptr(i*align))))
|
||||
case *int64:
|
||||
*v = int64(*(*C.int64_t)(unsafe.Pointer(uintptr(data) + uintptr(i*align))))
|
||||
case *uint:
|
||||
*v = uint(*(*C.unsigned)(unsafe.Pointer(uintptr(data) + uintptr(i*align))))
|
||||
case *uint8:
|
||||
*v = uint8(*(*C.uint8_t)(unsafe.Pointer(uintptr(data) + uintptr(i*align))))
|
||||
case *uint16:
|
||||
*v = uint16(*(*C.uint16_t)(unsafe.Pointer(uintptr(data) + uintptr(i*align))))
|
||||
case *uint32:
|
||||
*v = uint32(*(*C.uint32_t)(unsafe.Pointer(uintptr(data) + uintptr(i*align))))
|
||||
case *uint64:
|
||||
*v = uint64(*(*C.uint64_t)(unsafe.Pointer(uintptr(data) + uintptr(i*align))))
|
||||
case *uintptr:
|
||||
*v = uintptr(*(*C.uintptr_t)(unsafe.Pointer(uintptr(data) + uintptr(i*align))))
|
||||
case *string:
|
||||
s := *(**C.char)(unsafe.Pointer(uintptr(data) + uintptr(i*align)))
|
||||
*v = C.GoString(s)
|
||||
C.free(unsafe.Pointer(s))
|
||||
}
|
||||
}
|
||||
|
||||
if 1 >= fuse_args.argc {
|
||||
outargs = make([]string, 0)
|
||||
} else {
|
||||
outargs = make([]string, fuse_args.argc-1)
|
||||
for i := 1; int(fuse_args.argc) > i; i++ {
|
||||
outargs[i-1] = C.GoString((*[1 << 16]*C.char)(unsafe.Pointer(fuse_args.argv))[i])
|
||||
}
|
||||
}
|
||||
|
||||
if nonopts && 1 <= len(outargs) && "--" == outargs[0] {
|
||||
outargs = outargs[1:]
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func init() {
|
||||
C.hostStaticInit()
|
||||
}
|
||||
|
||||
+192
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* 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()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user