diff options
| author | Ophestra <cat@gensokyo.uk> | 2025-12-27 17:33:12 +0900 |
|---|---|---|
| committer | Ophestra <cat@gensokyo.uk> | 2025-12-27 17:33:12 +0900 |
| commit | 775a9f57c9ec3bc6877e3973a8c4972558707375 (patch) | |
| tree | 7410791c10ca3d8adfd8a17914ef799d55be1b5a /cmd/sharefs/fuse.go | |
| parent | 2f8ca8337633a199aae9b4cdd71c66ed1c9529a5 (diff) | |
cmd/sharefs: check option parsing behaviour
This change makes it possible to check parseOpts behaviour as part of Go tests.
Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'cmd/sharefs/fuse.go')
| -rw-r--r-- | cmd/sharefs/fuse.go | 44 |
1 files changed, 28 insertions, 16 deletions
diff --git a/cmd/sharefs/fuse.go b/cmd/sharefs/fuse.go index ea3d928e..9517b561 100644 --- a/cmd/sharefs/fuse.go +++ b/cmd/sharefs/fuse.go @@ -24,6 +24,7 @@ import ( "os" "os/exec" "os/signal" + "path" "runtime" "runtime/cgo" "strconv" @@ -43,6 +44,9 @@ type ( // closure represents a C function pointer. closure = C.closure + // fuseArgs represents the fuse_args structure. + fuseArgs = C.struct_fuse_args + // setupState holds state used for setup. Its cgo handle is included in // sharefs_private and considered opaque to non-setup callbacks. setupState struct { @@ -127,7 +131,14 @@ func sharefs_destroy(private_data unsafe.Pointer) { } // showHelp prints the help message. -func showHelp(args *C.struct_fuse_args) { +func showHelp(args *fuseArgs) { + executableName := sharefsName + if args.argc > 0 { + executableName = path.Base(C.GoString(*args.argv)) + } else if name, err := os.Executable(); err == nil { + executableName = path.Base(name) + } + fmt.Printf("usage: %s [options] <mountpoint>\n\n", executableName) fmt.Println("Filesystem options:") @@ -141,7 +152,7 @@ func showHelp(args *C.struct_fuse_args) { } // parseOpts parses fuse options via fuse_opt_parse. -func parseOpts(args *C.struct_fuse_args, setup *setupState) (ok bool) { +func parseOpts(args *fuseArgs, setup *setupState, log *log.Logger) (ok bool) { var unsafeOpts struct { // Pathname to writable source directory. source *C.char @@ -233,25 +244,28 @@ func parseOpts(args *C.struct_fuse_args, setup *setupState) (ok bool) { return true } -// copyStrings returns a copy of s with null-termination. -func copyStrings(s ...string) **C.char { +// copyArgs returns a heap allocated copy of an argument slice in fuse_args representation. +func copyArgs(s ...string) fuseArgs { if len(s) == 0 { - return nil + return fuseArgs{argc: 0, argv: nil, allocated: 0} } args := unsafe.Slice((**C.char)(C.malloc(C.size_t(uintptr(len(s))*unsafe.Sizeof(s[0])))), len(s)) for i, arg := range s { args[i] = C.CString(arg) } - return &args[0] + return fuseArgs{argc: C.int(len(s)), argv: &args[0], allocated: 1} } +// freeArgs frees the contents of argument list. +func freeArgs(args *fuseArgs) { C.fuse_opt_free_args(args) } + // unsafeAddArgument adds an argument to fuseArgs via fuse_opt_add_arg. // The last byte of arg must be 0. -func unsafeAddArgument(args *C.struct_fuse_args, arg string) { +func unsafeAddArgument(args *fuseArgs, arg string) { C.fuse_opt_add_arg(args, (*C.char)(unsafe.Pointer(unsafe.StringData(arg)))) } -func _main(argc int, argv **C.char) (exitCode int) { +func _main(s ...string) (exitCode int) { msg := message.New(log.Default()) container.TryArgv0(msg) runtime.LockOSThread() @@ -262,7 +276,8 @@ func _main(argc int, argv **C.char) (exitCode int) { var pinner runtime.Pinner defer pinner.Unpin() - args := C.struct_fuse_args{argc: C.int(argc), argv: argv, allocated: 1} + args := copyArgs(s...) + defer freeArgs(&args) // this causes the kernel to enforce access control based on // struct stat populated by sharefs_getattr @@ -278,12 +293,9 @@ func _main(argc int, argv **C.char) (exitCode int) { if C.fuse_parse_cmdline(&args, &opts) != 0 { return 1 } - defer func() { - if opts.mountpoint != nil { - C.free(unsafe.Pointer(opts.mountpoint)) - } - C.fuse_opt_free_args(&args) - }() + if opts.mountpoint != nil { + defer C.free(unsafe.Pointer(opts.mountpoint)) + } if opts.show_version != 0 { fmt.Println("hakurei version", info.Version()) @@ -315,7 +327,7 @@ func _main(argc int, argv **C.char) (exitCode int) { os.Args[pathnameArg] = container.Nonexistent } - if !parseOpts(&args, &setup) { + if !parseOpts(&args, &setup, msg.GetLogger()) { return 1 } |
