aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/app/dispatcher.go
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-09-25 13:46:21 +0900
committerOphestra <cat@gensokyo.uk>2025-09-25 13:51:54 +0900
commitae2df2c450dd655b93a950124b6ab16e2b4d967b (patch)
tree849ab40049228e17891351d97097f8c9d0e18c10 /internal/app/dispatcher.go
parent6e3f34f2ecfe0f3cd024a6e73bf6560080feac53 (diff)
internal: remove sys package
This package is replaced by container/stub. Remove and replace it with unexported implementation for the upcoming test suite rewrite. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/app/dispatcher.go')
-rw-r--r--internal/app/dispatcher.go99
1 files changed, 99 insertions, 0 deletions
diff --git a/internal/app/dispatcher.go b/internal/app/dispatcher.go
new file mode 100644
index 00000000..deecfa92
--- /dev/null
+++ b/internal/app/dispatcher.go
@@ -0,0 +1,99 @@
+package app
+
+import (
+ "log"
+ "os"
+ "os/exec"
+ "os/user"
+ "path/filepath"
+
+ "hakurei.app/container"
+ "hakurei.app/internal"
+ "hakurei.app/internal/hlog"
+)
+
+// syscallDispatcher provides methods that make state-dependent system calls as part of their behaviour.
+type syscallDispatcher interface {
+ // new starts a goroutine with a new instance of syscallDispatcher.
+ // A syscallDispatcher must never be used in any goroutine other than the one owning it,
+ // just synchronising access is not enough, as this is for test instrumentation.
+ new(f func(k syscallDispatcher))
+
+ // getuid provides [os.Getuid].
+ getuid() int
+ // getgid provides [os.Getgid].
+ getgid() int
+ // lookupEnv provides [os.LookupEnv].
+ lookupEnv(key string) (string, bool)
+ // stat provides [os.Stat].
+ stat(name string) (os.FileInfo, error)
+ // readdir provides [os.ReadDir].
+ readdir(name string) ([]os.DirEntry, error)
+ // tempdir provides [os.TempDir].
+ tempdir() string
+
+ // evalSymlinks provides [filepath.EvalSymlinks].
+ evalSymlinks(path string) (string, error)
+
+ // lookPath provides exec.LookPath.
+ lookPath(file string) (string, error)
+
+ // lookupGroupId calls [user.LookupGroup] and returns the Gid field of the resulting [user.Group] struct.
+ lookupGroupId(name string) (string, error)
+
+ // cmdOutput provides the Output method of [exec.Cmd].
+ cmdOutput(cmd *exec.Cmd) ([]byte, error)
+
+ // overflowUid provides [container.OverflowUid].
+ overflowUid() int
+ // overflowGid provides [container.OverflowGid].
+ overflowGid() int
+
+ // mustHsuPath provides [internal.MustHsuPath].
+ mustHsuPath() string
+
+ // fatalf provides [log.Fatalf].
+ fatalf(format string, v ...any)
+
+ isVerbose() bool
+ verbose(v ...any)
+ verbosef(format string, v ...any)
+}
+
+// direct implements syscallDispatcher on the current kernel.
+type direct struct{}
+
+func (k direct) new(f func(k syscallDispatcher)) { go f(k) }
+
+func (direct) getuid() int { return os.Getuid() }
+func (direct) getgid() int { return os.Getgid() }
+func (direct) lookupEnv(key string) (string, bool) { return os.LookupEnv(key) }
+func (direct) stat(name string) (os.FileInfo, error) { return os.Stat(name) }
+func (direct) readdir(name string) ([]os.DirEntry, error) { return os.ReadDir(name) }
+func (direct) tempdir() string { return os.TempDir() }
+
+func (direct) evalSymlinks(path string) (string, error) { return filepath.EvalSymlinks(path) }
+
+func (direct) lookPath(file string) (string, error) { return exec.LookPath(file) }
+
+func (direct) lookupGroupId(name string) (gid string, err error) {
+ var group *user.Group
+ group, err = user.LookupGroup(name)
+ if group != nil {
+ gid = group.Gid
+ }
+ return
+}
+
+func (direct) cmdOutput(cmd *exec.Cmd) ([]byte, error) { return cmd.Output() }
+
+func (direct) overflowUid() int { return container.OverflowUid() }
+func (direct) overflowGid() int { return container.OverflowGid() }
+
+func (direct) mustHsuPath() string { return internal.MustHsuPath() }
+
+func (direct) fatalf(format string, v ...any) { log.Fatalf(format, v...) }
+
+func (k direct) isVerbose() bool { return hlog.Load() }
+func (direct) verbose(v ...any) { hlog.Verbose(v...) }
+func (direct) verbosef(format string, v ...any) { hlog.Verbosef(format, v...) }