From ef1ebf12d98359c0d75ce48a1b05737f7e4e93c0 Mon Sep 17 00:00:00 2001 From: Ophestra Date: Sat, 27 Dec 2025 20:49:27 +0900 Subject: [PATCH] cmd/sharefs: handle mount -t fuse.sharefs This should have been handled in a custom option parsing function, but that much extra complexity is unnecessary for this edge case. Honestly I do not know why libfuse does not handle this itself. Signed-off-by: Ophestra --- cmd/sharefs/fuse.go | 6 +++--- cmd/sharefs/main.go | 17 ++++++++++++++++- cmd/sharefs/main_test.go | 29 +++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 cmd/sharefs/main_test.go diff --git a/cmd/sharefs/fuse.go b/cmd/sharefs/fuse.go index 9517b56..bbbc144 100644 --- a/cmd/sharefs/fuse.go +++ b/cmd/sharefs/fuse.go @@ -314,7 +314,7 @@ func _main(s ...string) (exitCode int) { // hack to keep fuse_parse_cmdline happy in the container mountpoint := C.GoString(opts.mountpoint) pathnameArg := -1 - for i, arg := range os.Args { + for i, arg := range s { if arg == mountpoint { pathnameArg = i break @@ -324,7 +324,7 @@ func _main(s ...string) (exitCode int) { log.Println("mountpoint must be absolute") return 2 } - os.Args[pathnameArg] = container.Nonexistent + s[pathnameArg] = container.Nonexistent } if !parseOpts(&args, &setup, msg.GetLogger()) { @@ -421,7 +421,7 @@ func _main(s ...string) (exitCode int) { } else { z.Path = a } - z.Args = os.Args + z.Args = s z.ForwardCancel = true z.SeccompPresets |= std.PresetStrict z.ParentPerm = 0700 diff --git a/cmd/sharefs/main.go b/cmd/sharefs/main.go index 941a166..c9fe9f2 100644 --- a/cmd/sharefs/main.go +++ b/cmd/sharefs/main.go @@ -3,14 +3,29 @@ package main import ( "log" "os" + "slices" ) // sharefsName is the prefix used by log.std in the sharefs process. const sharefsName = "sharefs" +// handleMountArgs returns an alternative, libfuse-compatible args slice for +// args passed by mount -t fuse.sharefs [options] sharefs . +// +// In this case, args always has a length of 5 with index 0 being what comes +// after "fuse." in the filesystem type, 1 is the uninterpreted string passed +// to mount (sharefsName is used as the magic string to enable this hack), +// 2 is passed through to libfuse as mountpoint, and 3 is always "-o". +func handleMountArgs(args []string) []string { + if len(args) == 5 && args[1] == sharefsName && args[3] == "-o" { + return []string{sharefsName, args[2], "-o", args[4]} + } + return slices.Clone(args) +} + func main() { log.SetFlags(0) log.SetPrefix(sharefsName + ": ") - os.Exit(_main(os.Args...)) + os.Exit(_main(handleMountArgs(os.Args)...)) } diff --git a/cmd/sharefs/main_test.go b/cmd/sharefs/main_test.go new file mode 100644 index 0000000..9498cd2 --- /dev/null +++ b/cmd/sharefs/main_test.go @@ -0,0 +1,29 @@ +package main + +import ( + "slices" + "testing" +) + +func TestHandleMountArgs(t *testing.T) { + t.Parallel() + + testCases := []struct { + name string + args []string + want []string + }{ + {"nil", nil, nil}, + {"passthrough", []string{"sharefs", "-V"}, []string{"sharefs", "-V"}}, + {"replace", []string{"/sbin/sharefs", "sharefs", "/sdcard", "-o", "rw"}, []string{"sharefs", "/sdcard", "-o", "rw"}}, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + + if got := handleMountArgs(tc.args); !slices.Equal(got, tc.want) { + t.Errorf("handleMountArgs: %q, want %q", got, tc.want) + } + }) + } +}