aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-11-13 07:08:07 +0900
committerOphestra <cat@gensokyo.uk>2025-11-13 07:14:16 +0900
commitabeb67964f52f245f7d529e4dfe01f8347932bfd (patch)
treeb2e00cedab6721261098dee789360571bdefa0cf
parentbf5d10743f82ea438b1a05939f55d8b0027e98b9 (diff)
treewide: document linkname uses
These provide justification for each use of linkname. Poorly thought out uses of linkname are removed. Signed-off-by: Ophestra <cat@gensokyo.uk>
-rw-r--r--cmd/hakurei/command.go7
-rw-r--r--cmd/hakurei/json_test.go12
-rw-r--r--container/check/absolute_test.go4
-rw-r--r--container/fhs/abs.go4
-rw-r--r--container/stub/exit_test.go4
-rw-r--r--hst/instance_test.go4
-rw-r--r--internal/outcome/main.go2
-rw-r--r--internal/store/data_test.go12
-rw-r--r--internal/store/segment_test.go23
-rw-r--r--internal/store/store_test.go4
10 files changed, 44 insertions, 32 deletions
diff --git a/cmd/hakurei/command.go b/cmd/hakurei/command.go
index e1f4c513..94fe7ead 100644
--- a/cmd/hakurei/command.go
+++ b/cmd/hakurei/command.go
@@ -11,7 +11,7 @@ import (
"strconv"
"sync"
"time"
- _ "unsafe"
+ _ "unsafe" // for go:linkname
"hakurei.app/command"
"hakurei.app/container/check"
@@ -24,8 +24,11 @@ import (
"hakurei.app/message"
)
+// optionalErrorUnwrap calls [errors.Unwrap] and returns the resulting value
+// if it is not nil, or the original value if it is.
+//
//go:linkname optionalErrorUnwrap hakurei.app/container.optionalErrorUnwrap
-func optionalErrorUnwrap(_ error) error
+func optionalErrorUnwrap(err error) error
func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErrs, out io.Writer) command.Command {
var (
diff --git a/cmd/hakurei/json_test.go b/cmd/hakurei/json_test.go
index 5e5daf0b..13e7e9f3 100644
--- a/cmd/hakurei/json_test.go
+++ b/cmd/hakurei/json_test.go
@@ -1,18 +1,13 @@
-package main_test
+package main
import (
- "io"
"reflect"
"strings"
"testing"
- _ "unsafe"
"hakurei.app/container/stub"
)
-//go:linkname decodeJSON hakurei.app/cmd/hakurei.decodeJSON
-func decodeJSON(fatal func(v ...any), op string, r io.Reader, v any)
-
func TestDecodeJSON(t *testing.T) {
t.Parallel()
@@ -62,9 +57,6 @@ func TestDecodeJSON(t *testing.T) {
}
}
-//go:linkname encodeJSON hakurei.app/cmd/hakurei.encodeJSON
-func encodeJSON(fatal func(v ...any), output io.Writer, short bool, v any)
-
func TestEncodeJSON(t *testing.T) {
t.Parallel()
@@ -74,7 +66,7 @@ func TestEncodeJSON(t *testing.T) {
want string
}{
{"marshaler", errorJSONMarshaler{},
- `cannot encode json for main_test.errorJSONMarshaler: unique error 3735928559 injected by the test suite`},
+ `cannot encode json for main.errorJSONMarshaler: unique error 3735928559 injected by the test suite`},
{"default", func() {},
`cannot write json: json: unsupported type: func()`},
}
diff --git a/container/check/absolute_test.go b/container/check/absolute_test.go
index 466bbacb..91cd3c92 100644
--- a/container/check/absolute_test.go
+++ b/container/check/absolute_test.go
@@ -14,8 +14,10 @@ import (
. "hakurei.app/container/check"
)
+// unsafeAbs returns check.Absolute on any string value.
+//
//go:linkname unsafeAbs hakurei.app/container/check.unsafeAbs
-func unsafeAbs(_ string) *Absolute
+func unsafeAbs(pathname string) *Absolute
func TestAbsoluteError(t *testing.T) {
t.Parallel()
diff --git a/container/fhs/abs.go b/container/fhs/abs.go
index 6bb72166..9175c1fe 100644
--- a/container/fhs/abs.go
+++ b/container/fhs/abs.go
@@ -8,8 +8,10 @@ import (
/* constants in this file bypass abs check, be extremely careful when changing them! */
+// unsafeAbs returns check.Absolute on any string value.
+//
//go:linkname unsafeAbs hakurei.app/container/check.unsafeAbs
-func unsafeAbs(_ string) *check.Absolute
+func unsafeAbs(pathname string) *check.Absolute
var (
// AbsRoot is [Root] as [check.Absolute].
diff --git a/container/stub/exit_test.go b/container/stub/exit_test.go
index e4c4f962..3e71c580 100644
--- a/container/stub/exit_test.go
+++ b/container/stub/exit_test.go
@@ -7,8 +7,10 @@ import (
"hakurei.app/container/stub"
)
+// Made available here to check panic recovery behaviour.
+//
//go:linkname handleExitNew hakurei.app/container/stub.handleExitNew
-func handleExitNew(_ testing.TB)
+func handleExitNew(t testing.TB)
// overrideTFailNow overrides the Fail and FailNow method.
type overrideTFailNow struct {
diff --git a/hst/instance_test.go b/hst/instance_test.go
index 5be9fc8b..290e7fbd 100644
--- a/hst/instance_test.go
+++ b/hst/instance_test.go
@@ -6,11 +6,13 @@ import (
"reflect"
"testing"
"time"
- _ "unsafe"
+ _ "unsafe" // for go:linkname
"hakurei.app/hst"
)
+// Made available here to check time encoding behaviour of [hst.ID].
+//
//go:linkname newInstanceID hakurei.app/hst.newInstanceID
func newInstanceID(id *hst.ID, p uint64) error
diff --git a/internal/outcome/main.go b/internal/outcome/main.go
index 1f02fafb..8bf666b2 100644
--- a/internal/outcome/main.go
+++ b/internal/outcome/main.go
@@ -12,6 +12,8 @@ import (
// IsPollDescriptor reports whether fd is the descriptor being used by the poller.
//
+// Made available here to determine and reject impossible fd.
+//
//go:linkname IsPollDescriptor internal/poll.IsPollDescriptor
func IsPollDescriptor(fd uintptr) bool
diff --git a/internal/store/data_test.go b/internal/store/data_test.go
index 62fd3c9a..fe0e2124 100644
--- a/internal/store/data_test.go
+++ b/internal/store/data_test.go
@@ -27,7 +27,7 @@ func TestEntryData(t *testing.T) {
return buf.String()
}
}
- templateStateGob := mustEncodeGob(newTemplateState())
+ templateStateGob := mustEncodeGob(NewTemplateState())
testCases := []struct {
name string
@@ -45,11 +45,11 @@ func TestEntryData(t *testing.T) {
Step: "validate configuration", Err: hst.ErrConfigNull,
Msg: "invalid configuration"}},
- {"inconsistent enablement", "\x00\xff\xca\xfe\x00\x00\xff\x00" + templateStateGob, newTemplateState(), &hst.AppError{
+ {"inconsistent enablement", "\x00\xff\xca\xfe\x00\x00\xff\x00" + templateStateGob, NewTemplateState(), &hst.AppError{
Step: "validate state enablement", Err: os.ErrInvalid,
Msg: "state entry aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa has unexpected enablement byte 0xd, 0xff"}},
- {"template", "\x00\xff\xca\xfe\x00\x00\x0d\xf2" + templateStateGob, newTemplateState(), nil},
+ {"template", "\x00\xff\xca\xfe\x00\x00\x0d\xf2" + templateStateGob, NewTemplateState(), nil},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
@@ -105,7 +105,7 @@ func TestEntryData(t *testing.T) {
t.Run("encode fault", func(t *testing.T) {
t.Parallel()
- s := newTemplateState()
+ s := NewTemplateState()
t.Run("gob", func(t *testing.T) {
var want = &hst.AppError{Step: "encode state body", Err: stub.UniqueError(0xcafe)}
@@ -123,8 +123,8 @@ func TestEntryData(t *testing.T) {
})
}
-// newTemplateState returns the address of a new template [hst.State] struct.
-func newTemplateState() *hst.State {
+// NewTemplateState returns the address of a new template [hst.State] struct.
+func NewTemplateState() *hst.State {
return &hst.State{
ID: hst.ID(bytes.Repeat([]byte{0xaa}, len(hst.ID{}))),
PID: 0xcafe,
diff --git a/internal/store/segment_test.go b/internal/store/segment_test.go
index 8d4d7f3b..67915459 100644
--- a/internal/store/segment_test.go
+++ b/internal/store/segment_test.go
@@ -10,7 +10,7 @@ import (
"strings"
"syscall"
"testing"
- _ "unsafe"
+ _ "unsafe" // for go:linkname
"hakurei.app/container/check"
"hakurei.app/container/stub"
@@ -18,18 +18,23 @@ import (
"hakurei.app/internal/store"
)
-//go:linkname newTemplateState hakurei.app/internal/store.newTemplateState
-func newTemplateState() *hst.State
-
+// Made available here for direct validation of state entry files.
+//
//go:linkname entryDecode hakurei.app/internal/store.entryDecode
func entryDecode(r io.Reader, p *hst.State) (hst.Enablement, error)
+// Made available here for direct access to known segment handles.
+//
//go:linkname newHandle hakurei.app/internal/store.newHandle
func newHandle(base *check.Absolute, identity int) *store.Handle
+// Made available here to check open error handling behaviour.
+//
//go:linkname open hakurei.app/internal/store.(*EntryHandle).open
func open(eh *store.EntryHandle, flag int, perm os.FileMode) (*os.File, error)
+// Made available here to check the saveload cycle.
+//
//go:linkname save hakurei.app/internal/store.(*EntryHandle).save
func save(eh *store.EntryHandle, state *hst.State) error
@@ -91,9 +96,9 @@ func TestStateEntryHandle(t *testing.T) {
t.Run("saveload", func(t *testing.T) {
t.Parallel()
eh := store.EntryHandle{Pathname: check.MustAbs(t.TempDir()).Append("entry"),
- ID: newTemplateState().ID}
+ ID: store.NewTemplateState().ID}
- if err := save(&eh, newTemplateState()); err != nil {
+ if err := save(&eh, store.NewTemplateState()); err != nil {
t.Fatalf("save: error = %v", err)
}
@@ -112,7 +117,7 @@ func TestStateEntryHandle(t *testing.T) {
t.Fatal(f.Close())
}
- if want := newTemplateState(); !reflect.DeepEqual(&got, want) {
+ if want := store.NewTemplateState(); !reflect.DeepEqual(&got, want) {
t.Errorf("entryDecode: %#v, want %#v", &got, want)
}
})
@@ -122,7 +127,7 @@ func TestStateEntryHandle(t *testing.T) {
if et, err := eh.Load(nil); err != nil {
t.Fatalf("load: error = %v", err)
- } else if want := newTemplateState().Enablements.Unwrap(); et != want {
+ } else if want := store.NewTemplateState().Enablements.Unwrap(); et != want {
t.Errorf("load: et = %x, want %x", et, want)
}
})
@@ -133,7 +138,7 @@ func TestStateEntryHandle(t *testing.T) {
var got hst.State
if _, err := eh.Load(&got); err != nil {
t.Fatalf("load: error = %v", err)
- } else if want := newTemplateState(); !reflect.DeepEqual(&got, want) {
+ } else if want := store.NewTemplateState(); !reflect.DeepEqual(&got, want) {
t.Errorf("load: %#v, want %#v", &got, want)
}
})
diff --git a/internal/store/store_test.go b/internal/store/store_test.go
index 54f28bdd..9abf480e 100644
--- a/internal/store/store_test.go
+++ b/internal/store/store_test.go
@@ -12,13 +12,15 @@ import (
"syscall"
"testing"
"time"
- _ "unsafe"
+ _ "unsafe" // for go:linkname
"hakurei.app/container/check"
"hakurei.app/hst"
"hakurei.app/internal/store"
)
+// Made available here to check bigLock error handling behaviour.
+//
//go:linkname bigLock hakurei.app/internal/store.(*Store).bigLock
func bigLock(s *store.Store) (unlock func(), err error)