From e68db7fbfc367f25ccbaf57ec43f0f4b3c93cba7 Mon Sep 17 00:00:00 2001 From: Ophestra Date: Sat, 6 Sep 2025 16:16:03 +0900 Subject: [PATCH] system: unexport Op implementations None of these are valid with their zero value, and the implementations assume they are created by the builder methods. They are by all means an implementation detail and exporting them makes no sense. Signed-off-by: Ophestra --- system/acl.go | 24 ++++++------ system/acl_test.go | 82 ++++++++++++++++++++--------------------- system/dbus.go | 24 ++++++------ system/dbus_test.go | 44 +++++++++++----------- system/link.go | 24 ++++++------ system/mkdir.go | 27 +++++++------- system/mkdir_test.go | 6 +-- system/tmpfiles.go | 25 +++++++------ system/tmpfiles_test.go | 8 ++-- system/wayland.go | 26 ++++++------- system/xhost.go | 20 +++++----- system/xhost_test.go | 4 +- 12 files changed, 157 insertions(+), 157 deletions(-) diff --git a/system/acl.go b/system/acl.go index 4052d01..b49b3df 100644 --- a/system/acl.go +++ b/system/acl.go @@ -9,33 +9,33 @@ import ( "hakurei.app/system/acl" ) -// UpdatePerm appends [ACLUpdateOp] to [I] with the [Process] criteria. +// UpdatePerm calls UpdatePermType with the [Process] criteria. func (sys *I) UpdatePerm(path string, perms ...acl.Perm) *I { sys.UpdatePermType(Process, path, perms...) return sys } -// UpdatePermType appends [ACLUpdateOp] to [I]. +// UpdatePermType maintains [acl.Perms] on a file until its [Enablement] is no longer satisfied. func (sys *I) UpdatePermType(et Enablement, path string, perms ...acl.Perm) *I { - sys.ops = append(sys.ops, &ACLUpdateOp{et, path, perms}) + sys.ops = append(sys.ops, &aclUpdateOp{et, path, perms}) return sys } -// ACLUpdateOp maintains [acl.Perms] on a file until its [Enablement] is no longer satisfied. -type ACLUpdateOp struct { +// aclUpdateOp implements [I.UpdatePermType]. +type aclUpdateOp struct { et Enablement path string perms acl.Perms } -func (a *ACLUpdateOp) Type() Enablement { return a.et } +func (a *aclUpdateOp) Type() Enablement { return a.et } -func (a *ACLUpdateOp) apply(sys *I) error { +func (a *aclUpdateOp) apply(sys *I) error { sys.verbose("applying ACL", a) return newOpError("acl", sys.aclUpdate(a.path, sys.uid, a.perms...), false) } -func (a *ACLUpdateOp) revert(sys *I, ec *Criteria) error { +func (a *aclUpdateOp) revert(sys *I, ec *Criteria) error { if ec.hasType(a.Type()) { sys.verbose("stripping ACL", a) err := sys.aclUpdate(a.path, sys.uid) @@ -51,17 +51,17 @@ func (a *ACLUpdateOp) revert(sys *I, ec *Criteria) error { } } -func (a *ACLUpdateOp) Is(o Op) bool { - target, ok := o.(*ACLUpdateOp) +func (a *aclUpdateOp) Is(o Op) bool { + target, ok := o.(*aclUpdateOp) return ok && a != nil && target != nil && a.et == target.et && a.path == target.path && slices.Equal(a.perms, target.perms) } -func (a *ACLUpdateOp) Path() string { return a.path } +func (a *aclUpdateOp) Path() string { return a.path } -func (a *ACLUpdateOp) String() string { +func (a *aclUpdateOp) String() string { return fmt.Sprintf("%s type: %s path: %q", a.perms, TypeString(a.et), a.path) } diff --git a/system/acl_test.go b/system/acl_test.go index a92e38b..910e5a1 100644 --- a/system/acl_test.go +++ b/system/acl_test.go @@ -12,44 +12,44 @@ import ( func TestACLUpdateOp(t *testing.T) { checkOpBehaviour(t, []opBehaviourTestCase{ {"apply aclUpdate", 0xdeadbeef, 0xff, - &ACLUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}, []stub.Call{ - call("verbose", stub.ExpectArgs{[]any{"applying ACL", &ACLUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}}}, nil, nil), + &aclUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}, []stub.Call{ + call("verbose", stub.ExpectArgs{[]any{"applying ACL", &aclUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}}}, nil, nil), call("aclUpdate", stub.ExpectArgs{"/proc/nonexistent", 0xdeadbeef, []acl.Perm{acl.Read, acl.Write, acl.Execute}}, nil, stub.UniqueError(1)), }, &OpError{Op: "acl", Err: stub.UniqueError(1)}, nil, nil}, {"revert aclUpdate", 0xdeadbeef, 0xff, - &ACLUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}, []stub.Call{ - call("verbose", stub.ExpectArgs{[]any{"applying ACL", &ACLUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}}}, nil, nil), + &aclUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}, []stub.Call{ + call("verbose", stub.ExpectArgs{[]any{"applying ACL", &aclUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}}}, nil, nil), call("aclUpdate", stub.ExpectArgs{"/proc/nonexistent", 0xdeadbeef, []acl.Perm{acl.Read, acl.Write, acl.Execute}}, nil, nil), }, nil, []stub.Call{ - call("verbose", stub.ExpectArgs{[]any{"stripping ACL", &ACLUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}}}, nil, nil), + call("verbose", stub.ExpectArgs{[]any{"stripping ACL", &aclUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}}}, nil, nil), call("aclUpdate", stub.ExpectArgs{"/proc/nonexistent", 0xdeadbeef, ([]acl.Perm)(nil)}, nil, stub.UniqueError(0)), }, &OpError{Op: "acl", Err: stub.UniqueError(0), Revert: true}}, {"success revert skip", 0xdeadbeef, Process, - &ACLUpdateOp{User, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}, []stub.Call{ - call("verbose", stub.ExpectArgs{[]any{"applying ACL", &ACLUpdateOp{User, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}}}, nil, nil), + &aclUpdateOp{User, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}, []stub.Call{ + call("verbose", stub.ExpectArgs{[]any{"applying ACL", &aclUpdateOp{User, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}}}, nil, nil), call("aclUpdate", stub.ExpectArgs{"/proc/nonexistent", 0xdeadbeef, []acl.Perm{acl.Read, acl.Write, acl.Execute}}, nil, nil), }, nil, []stub.Call{ - call("verbose", stub.ExpectArgs{[]any{"skipping ACL", &ACLUpdateOp{User, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}}}, nil, nil), + call("verbose", stub.ExpectArgs{[]any{"skipping ACL", &aclUpdateOp{User, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}}}, nil, nil), }, nil}, {"success revert aclUpdate ENOENT", 0xdeadbeef, 0xff, - &ACLUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}, []stub.Call{ - call("verbose", stub.ExpectArgs{[]any{"applying ACL", &ACLUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}}}, nil, nil), + &aclUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}, []stub.Call{ + call("verbose", stub.ExpectArgs{[]any{"applying ACL", &aclUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}}}, nil, nil), call("aclUpdate", stub.ExpectArgs{"/proc/nonexistent", 0xdeadbeef, []acl.Perm{acl.Read, acl.Write, acl.Execute}}, nil, nil), }, nil, []stub.Call{ - call("verbose", stub.ExpectArgs{[]any{"stripping ACL", &ACLUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}}}, nil, nil), + call("verbose", stub.ExpectArgs{[]any{"stripping ACL", &aclUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}}}, nil, nil), call("aclUpdate", stub.ExpectArgs{"/proc/nonexistent", 0xdeadbeef, ([]acl.Perm)(nil)}, nil, &os.PathError{Op: "acl_get_file", Path: "/proc/nonexistent", Err: syscall.ENOENT}), - call("verbosef", stub.ExpectArgs{"target of ACL %s no longer exists", []any{&ACLUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}}}, nil, nil), + call("verbosef", stub.ExpectArgs{"target of ACL %s no longer exists", []any{&aclUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}}}, nil, nil), }, nil}, {"success", 0xdeadbeef, 0xff, - &ACLUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}, []stub.Call{ - call("verbose", stub.ExpectArgs{[]any{"applying ACL", &ACLUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}}}, nil, nil), + &aclUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}, []stub.Call{ + call("verbose", stub.ExpectArgs{[]any{"applying ACL", &aclUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}}}, nil, nil), call("aclUpdate", stub.ExpectArgs{"/proc/nonexistent", 0xdeadbeef, []acl.Perm{acl.Read, acl.Write, acl.Execute}}, nil, nil), }, nil, []stub.Call{ - call("verbose", stub.ExpectArgs{[]any{"stripping ACL", &ACLUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}}}, nil, nil), + call("verbose", stub.ExpectArgs{[]any{"stripping ACL", &aclUpdateOp{Process, "/proc/nonexistent", []acl.Perm{acl.Read, acl.Write, acl.Execute}}}}, nil, nil), call("aclUpdate", stub.ExpectArgs{"/proc/nonexistent", 0xdeadbeef, ([]acl.Perm)(nil)}, nil, nil), }, nil}, }) @@ -62,27 +62,27 @@ func TestACLUpdateOp(t *testing.T) { UpdatePerm("/run/user/1971/hakurei", acl.Execute). UpdatePerm("/tmp/hakurei.0/tmpdir/150", acl.Read, acl.Write, acl.Execute) }, []Op{ - &ACLUpdateOp{Process, "/run/user/1971/hakurei", []acl.Perm{acl.Execute}}, - &ACLUpdateOp{Process, "/tmp/hakurei.0/tmpdir/150", []acl.Perm{acl.Read, acl.Write, acl.Execute}}, + &aclUpdateOp{Process, "/run/user/1971/hakurei", []acl.Perm{acl.Execute}}, + &aclUpdateOp{Process, "/tmp/hakurei.0/tmpdir/150", []acl.Perm{acl.Read, acl.Write, acl.Execute}}, }, stub.Expect{}}, }) checkOpsBuilder(t, "UpdatePermType", []opsBuilderTestCase{ {"tmpdirp", 0xdeadbeef, func(_ *testing.T, sys *I) { sys.UpdatePermType(User, "/tmp/hakurei.0/tmpdir", acl.Execute) }, []Op{ - &ACLUpdateOp{User, "/tmp/hakurei.0/tmpdir", []acl.Perm{acl.Execute}}, + &aclUpdateOp{User, "/tmp/hakurei.0/tmpdir", []acl.Perm{acl.Execute}}, }, stub.Expect{}}, {"tmpdir", 0xdeadbeef, func(_ *testing.T, sys *I) { sys.UpdatePermType(User, "/tmp/hakurei.0/tmpdir/150", acl.Read, acl.Write, acl.Execute) }, []Op{ - &ACLUpdateOp{User, "/tmp/hakurei.0/tmpdir/150", []acl.Perm{acl.Read, acl.Write, acl.Execute}}, + &aclUpdateOp{User, "/tmp/hakurei.0/tmpdir/150", []acl.Perm{acl.Read, acl.Write, acl.Execute}}, }, stub.Expect{}}, {"share", 0xdeadbeef, func(_ *testing.T, sys *I) { sys.UpdatePermType(Process, "/run/user/1971/hakurei/fcb8a12f7c482d183ade8288c3de78b5", acl.Execute) }, []Op{ - &ACLUpdateOp{Process, "/run/user/1971/hakurei/fcb8a12f7c482d183ade8288c3de78b5", []acl.Perm{acl.Execute}}, + &aclUpdateOp{Process, "/run/user/1971/hakurei/fcb8a12f7c482d183ade8288c3de78b5", []acl.Perm{acl.Execute}}, }, stub.Expect{}}, {"passwd", 0xdeadbeef, func(_ *testing.T, sys *I) { @@ -90,50 +90,50 @@ func TestACLUpdateOp(t *testing.T) { UpdatePermType(Process, "/tmp/hakurei.0/fcb8a12f7c482d183ade8288c3de78b5/passwd", acl.Read). UpdatePermType(Process, "/tmp/hakurei.0/fcb8a12f7c482d183ade8288c3de78b5/group", acl.Read) }, []Op{ - &ACLUpdateOp{Process, "/tmp/hakurei.0/fcb8a12f7c482d183ade8288c3de78b5/passwd", []acl.Perm{acl.Read}}, - &ACLUpdateOp{Process, "/tmp/hakurei.0/fcb8a12f7c482d183ade8288c3de78b5/group", []acl.Perm{acl.Read}}, + &aclUpdateOp{Process, "/tmp/hakurei.0/fcb8a12f7c482d183ade8288c3de78b5/passwd", []acl.Perm{acl.Read}}, + &aclUpdateOp{Process, "/tmp/hakurei.0/fcb8a12f7c482d183ade8288c3de78b5/group", []acl.Perm{acl.Read}}, }, stub.Expect{}}, {"wayland", 0xdeadbeef, func(_ *testing.T, sys *I) { sys.UpdatePermType(EWayland, "/run/user/1971/wayland-0", acl.Read, acl.Write, acl.Execute) }, []Op{ - &ACLUpdateOp{EWayland, "/run/user/1971/wayland-0", []acl.Perm{acl.Read, acl.Write, acl.Execute}}, + &aclUpdateOp{EWayland, "/run/user/1971/wayland-0", []acl.Perm{acl.Read, acl.Write, acl.Execute}}, }, stub.Expect{}}, }) checkOpIs(t, []opIsTestCase{ - {"nil", (*ACLUpdateOp)(nil), (*ACLUpdateOp)(nil), false}, - {"zero", new(ACLUpdateOp), new(ACLUpdateOp), true}, + {"nil", (*aclUpdateOp)(nil), (*aclUpdateOp)(nil), false}, + {"zero", new(aclUpdateOp), new(aclUpdateOp), true}, {"et differs", - &ACLUpdateOp{ + &aclUpdateOp{ EWayland, "/run/user/1971/wayland-0", []acl.Perm{acl.Read, acl.Write, acl.Execute}, - }, &ACLUpdateOp{ + }, &aclUpdateOp{ EX11, "/run/user/1971/wayland-0", []acl.Perm{acl.Read, acl.Write, acl.Execute}, }, false}, - {"path differs", &ACLUpdateOp{ + {"path differs", &aclUpdateOp{ EWayland, "/run/user/1971/wayland-0", []acl.Perm{acl.Read, acl.Write, acl.Execute}, - }, &ACLUpdateOp{ + }, &aclUpdateOp{ EWayland, "/run/user/1971/wayland-1", []acl.Perm{acl.Read, acl.Write, acl.Execute}, }, false}, - {"perms differs", &ACLUpdateOp{ + {"perms differs", &aclUpdateOp{ EWayland, "/run/user/1971/wayland-0", []acl.Perm{acl.Read, acl.Write, acl.Execute}, - }, &ACLUpdateOp{ + }, &aclUpdateOp{ EWayland, "/run/user/1971/wayland-0", []acl.Perm{acl.Read, acl.Write}, }, false}, - {"equals", &ACLUpdateOp{ + {"equals", &aclUpdateOp{ EWayland, "/run/user/1971/wayland-0", []acl.Perm{acl.Read, acl.Write, acl.Execute}, - }, &ACLUpdateOp{ + }, &aclUpdateOp{ EWayland, "/run/user/1971/wayland-0", []acl.Perm{acl.Read, acl.Write, acl.Execute}, }, true}, @@ -141,42 +141,42 @@ func TestACLUpdateOp(t *testing.T) { checkOpMeta(t, []opMetaTestCase{ {"clear", - &ACLUpdateOp{Process, "/proc/nonexistent", []acl.Perm{}}, + &aclUpdateOp{Process, "/proc/nonexistent", []acl.Perm{}}, Process, "/proc/nonexistent", `--- type: process path: "/proc/nonexistent"`}, {"read", - &ACLUpdateOp{User, "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/0", []acl.Perm{acl.Read}}, + &aclUpdateOp{User, "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/0", []acl.Perm{acl.Read}}, User, "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/0", `r-- type: user path: "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/0"`}, {"write", - &ACLUpdateOp{User, "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/1", []acl.Perm{acl.Write}}, + &aclUpdateOp{User, "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/1", []acl.Perm{acl.Write}}, User, "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/1", `-w- type: user path: "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/1"`}, {"execute", - &ACLUpdateOp{User, "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/2", []acl.Perm{acl.Execute}}, + &aclUpdateOp{User, "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/2", []acl.Perm{acl.Execute}}, User, "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/2", `--x type: user path: "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/2"`}, {"wayland", - &ACLUpdateOp{EWayland, "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/wayland", []acl.Perm{acl.Read, acl.Write}}, + &aclUpdateOp{EWayland, "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/wayland", []acl.Perm{acl.Read, acl.Write}}, EWayland, "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/wayland", `rw- type: wayland path: "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/wayland"`}, {"x11", - &ACLUpdateOp{EX11, "/tmp/.X11-unix/X0", []acl.Perm{acl.Read, acl.Execute}}, + &aclUpdateOp{EX11, "/tmp/.X11-unix/X0", []acl.Perm{acl.Read, acl.Execute}}, EX11, "/tmp/.X11-unix/X0", `r-x type: x11 path: "/tmp/.X11-unix/X0"`}, {"dbus", - &ACLUpdateOp{EDBus, "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/bus", []acl.Perm{acl.Write, acl.Execute}}, + &aclUpdateOp{EDBus, "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/bus", []acl.Perm{acl.Write, acl.Execute}}, EDBus, "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/bus", `-wx type: dbus path: "/tmp/hakurei.0/27d81d567f8fae7f33278eec45da9446/bus"`}, {"pulseaudio", - &ACLUpdateOp{EPulse, "/run/user/1971/hakurei/27d81d567f8fae7f33278eec45da9446/pulse", []acl.Perm{acl.Read, acl.Write, acl.Execute}}, + &aclUpdateOp{EPulse, "/run/user/1971/hakurei/27d81d567f8fae7f33278eec45da9446/pulse", []acl.Perm{acl.Read, acl.Write, acl.Execute}}, EPulse, "/run/user/1971/hakurei/27d81d567f8fae7f33278eec45da9446/pulse", `rwx type: pulseaudio path: "/run/user/1971/hakurei/27d81d567f8fae7f33278eec45da9446/pulse"`}, }) diff --git a/system/dbus.go b/system/dbus.go index 3348bf6..de52e78 100644 --- a/system/dbus.go +++ b/system/dbus.go @@ -28,9 +28,10 @@ func (sys *I) MustProxyDBus(sessionPath string, session *dbus.Config, systemPath } } -// ProxyDBus finalises configuration and appends [DBusProxyOp] to [I]. +// ProxyDBus finalises configuration ahead of time and starts xdg-dbus-proxy via [dbus] and terminates it on revert. +// This [Op] is always [Process] scoped. func (sys *I) ProxyDBus(session, system *dbus.Config, sessionPath, systemPath string) (func(), error) { - d := new(DBusProxyOp) + d := new(dbusProxyOp) // session bus is required as otherwise this is effectively a very expensive noop if session == nil { @@ -70,9 +71,8 @@ func (sys *I) ProxyDBus(session, system *dbus.Config, sessionPath, systemPath st return d.out.Dump, nil } -// DBusProxyOp starts xdg-dbus-proxy via [dbus] and terminates it on revert. -// This [Op] is always [Process] scoped. -type DBusProxyOp struct { +// dbusProxyOp implements [I.ProxyDBus]. +type dbusProxyOp struct { proxy *dbus.Proxy // populated during apply final *dbus.Final @@ -81,9 +81,9 @@ type DBusProxyOp struct { system bool } -func (d *DBusProxyOp) Type() Enablement { return Process } +func (d *dbusProxyOp) Type() Enablement { return Process } -func (d *DBusProxyOp) apply(sys *I) error { +func (d *dbusProxyOp) apply(sys *I) error { sys.verbosef("session bus proxy on %q for upstream %q", d.final.Session[1], d.final.Session[0]) if d.system { sys.verbosef("system bus proxy on %q for upstream %q", d.final.System[1], d.final.System[0]) @@ -99,7 +99,7 @@ func (d *DBusProxyOp) apply(sys *I) error { return nil } -func (d *DBusProxyOp) revert(sys *I, _ *Criteria) error { +func (d *dbusProxyOp) revert(sys *I, _ *Criteria) error { // criteria ignored here since dbus is always process-scoped sys.verbose("terminating message bus proxy") sys.dbusProxyClose(d.proxy) @@ -116,8 +116,8 @@ func (d *DBusProxyOp) revert(sys *I, _ *Criteria) error { fmt.Sprintf("message bus proxy error: %v", err), true) } -func (d *DBusProxyOp) Is(o Op) bool { - target, ok := o.(*DBusProxyOp) +func (d *dbusProxyOp) Is(o Op) bool { + target, ok := o.(*dbusProxyOp) return ok && d != nil && target != nil && d.system == target.system && d.final != nil && target.final != nil && @@ -128,8 +128,8 @@ func (d *DBusProxyOp) Is(o Op) bool { reflect.DeepEqual(d.final.WriterTo, target.final.WriterTo) } -func (d *DBusProxyOp) Path() string { return container.Nonexistent } -func (d *DBusProxyOp) String() string { return d.proxy.String() } +func (d *dbusProxyOp) Path() string { return container.Nonexistent } +func (d *dbusProxyOp) String() string { return d.proxy.String() } const ( // lpwSizeThreshold is the threshold of bytes written to linePrefixWriter which, diff --git a/system/dbus_test.go b/system/dbus_test.go index 7ad7bb2..1ae217b 100644 --- a/system/dbus_test.go +++ b/system/dbus_test.go @@ -16,7 +16,7 @@ import ( func TestDBusProxyOp(t *testing.T) { checkOpBehaviour(t, []opBehaviourTestCase{ - {"dbusProxyStart", 0xdeadbeef, 0xff, &DBusProxyOp{ + {"dbusProxyStart", 0xdeadbeef, 0xff, &dbusProxyOp{ final: dbusNewFinalSample(4), out: new(linePrefixWriter), // panics on write system: true, @@ -29,7 +29,7 @@ func TestDBusProxyOp(t *testing.T) { Msg: "cannot start message bus proxy: unique error 2 injected by the test suite", }, nil, nil}, - {"dbusProxyWait", 0xdeadbeef, 0xff, &DBusProxyOp{ + {"dbusProxyWait", 0xdeadbeef, 0xff, &dbusProxyOp{ final: dbusNewFinalSample(3), }, []stub.Call{ call("verbosef", stub.ExpectArgs{"session bus proxy on %q for upstream %q", []any{"/tmp/hakurei.0/99dd71ee2146369514e0d10783368f8f/bus", "unix:path=/run/user/1000/bus"}}, nil, nil), @@ -45,7 +45,7 @@ func TestDBusProxyOp(t *testing.T) { Msg: "message bus proxy error: unique error 1 injected by the test suite", }}, - {"success dbusProxyWait cancel", 0xdeadbeef, 0xff, &DBusProxyOp{ + {"success dbusProxyWait cancel", 0xdeadbeef, 0xff, &dbusProxyOp{ final: dbusNewFinalSample(2), system: true, }, []stub.Call{ @@ -60,7 +60,7 @@ func TestDBusProxyOp(t *testing.T) { call("verbose", stub.ExpectArgs{[]any{"message bus proxy canceled upstream"}}, nil, nil), }, nil}, - {"success", 0xdeadbeef, 0xff, &DBusProxyOp{ + {"success", 0xdeadbeef, 0xff, &dbusProxyOp{ final: dbusNewFinalSample(1), system: true, }, []stub.Call{ @@ -154,7 +154,7 @@ func TestDBusProxyOp(t *testing.T) { Talk: []string{"system\x00"}, Filter: true, }) }, []Op{ - &DBusProxyOp{ + &dbusProxyOp{ final: dbusNewFinalSample(0), system: true, }, @@ -174,10 +174,10 @@ func TestDBusProxyOp(t *testing.T) { }) checkOpIs(t, []opIsTestCase{ - {"nil", (*DBusProxyOp)(nil), (*DBusProxyOp)(nil), false}, - {"zero", new(DBusProxyOp), new(DBusProxyOp), false}, + {"nil", (*dbusProxyOp)(nil), (*dbusProxyOp)(nil), false}, + {"zero", new(dbusProxyOp), new(dbusProxyOp), false}, - {"system differs", &DBusProxyOp{final: &dbus.Final{ + {"system differs", &dbusProxyOp{final: &dbus.Final{ Session: dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus"}, System: dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket"}, @@ -189,7 +189,7 @@ func TestDBusProxyOp(t *testing.T) { "--filter", "unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket", }), }, system: false, - }, &DBusProxyOp{final: &dbus.Final{ + }, &dbusProxyOp{final: &dbus.Final{ Session: dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus"}, System: dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket"}, @@ -203,7 +203,7 @@ func TestDBusProxyOp(t *testing.T) { }, system: true, }, false}, - {"wt differs", &DBusProxyOp{final: &dbus.Final{ + {"wt differs", &dbusProxyOp{final: &dbus.Final{ Session: dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus"}, System: dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket"}, @@ -215,7 +215,7 @@ func TestDBusProxyOp(t *testing.T) { "--filter", "unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket", }), }, system: true, - }, &DBusProxyOp{final: &dbus.Final{ + }, &dbusProxyOp{final: &dbus.Final{ Session: dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus"}, System: dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket"}, @@ -229,7 +229,7 @@ func TestDBusProxyOp(t *testing.T) { }, system: true, }, false}, - {"final system upstream differs", &DBusProxyOp{final: &dbus.Final{ + {"final system upstream differs", &dbusProxyOp{final: &dbus.Final{ Session: dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus"}, System: dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket"}, @@ -241,7 +241,7 @@ func TestDBusProxyOp(t *testing.T) { "--filter", "unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket", }), }, system: true, - }, &DBusProxyOp{final: &dbus.Final{ + }, &dbusProxyOp{final: &dbus.Final{ Session: dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus"}, System: dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket"}, @@ -255,7 +255,7 @@ func TestDBusProxyOp(t *testing.T) { }, system: true, }, false}, - {"final session upstream differs", &DBusProxyOp{final: &dbus.Final{ + {"final session upstream differs", &dbusProxyOp{final: &dbus.Final{ Session: dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus"}, System: dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket"}, @@ -267,7 +267,7 @@ func TestDBusProxyOp(t *testing.T) { "--filter", "unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket", }), }, system: true, - }, &DBusProxyOp{final: &dbus.Final{ + }, &dbusProxyOp{final: &dbus.Final{ Session: dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus"}, System: dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket"}, @@ -281,7 +281,7 @@ func TestDBusProxyOp(t *testing.T) { }, system: true, }, false}, - {"final system differs", &DBusProxyOp{final: &dbus.Final{ + {"final system differs", &dbusProxyOp{final: &dbus.Final{ Session: dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus"}, System: dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.1/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket"}, @@ -293,7 +293,7 @@ func TestDBusProxyOp(t *testing.T) { "--filter", "unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket", }), }, system: true, - }, &DBusProxyOp{final: &dbus.Final{ + }, &dbusProxyOp{final: &dbus.Final{ Session: dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus"}, System: dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket"}, @@ -307,7 +307,7 @@ func TestDBusProxyOp(t *testing.T) { }, system: true, }, false}, - {"final session differs", &DBusProxyOp{final: &dbus.Final{ + {"final session differs", &dbusProxyOp{final: &dbus.Final{ Session: dbus.ProxyPair{"unix:path=/run/user/1001/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus"}, System: dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket"}, @@ -319,7 +319,7 @@ func TestDBusProxyOp(t *testing.T) { "--filter", "unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket", }), }, system: true, - }, &DBusProxyOp{final: &dbus.Final{ + }, &dbusProxyOp{final: &dbus.Final{ Session: dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus"}, System: dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket"}, @@ -333,7 +333,7 @@ func TestDBusProxyOp(t *testing.T) { }, system: true, }, false}, - {"equals", &DBusProxyOp{final: &dbus.Final{ + {"equals", &dbusProxyOp{final: &dbus.Final{ Session: dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus"}, System: dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket"}, @@ -345,7 +345,7 @@ func TestDBusProxyOp(t *testing.T) { "--filter", "unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket", }), }, system: true, - }, &DBusProxyOp{final: &dbus.Final{ + }, &dbusProxyOp{final: &dbus.Final{ Session: dbus.ProxyPair{"unix:path=/run/user/1000/bus", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/bus"}, System: dbus.ProxyPair{"unix:path=/run/dbus/system_bus_socket", "/tmp/hakurei.0/b186c281d9e83a39afdc66d964ef99c6/system_bus_socket"}, @@ -361,7 +361,7 @@ func TestDBusProxyOp(t *testing.T) { }) checkOpMeta(t, []opMetaTestCase{ - {"dbus", new(DBusProxyOp), + {"dbus", new(dbusProxyOp), Process, "/proc/nonexistent", "(invalid dbus proxy)"}, }) diff --git a/system/link.go b/system/link.go index 544443e..8df85fc 100644 --- a/system/link.go +++ b/system/link.go @@ -5,29 +5,29 @@ import ( "os" ) -// Link appends [HardlinkOp] to [I] the [Process] criteria. +// Link calls LinkFileType with the [Process] criteria. func (sys *I) Link(oldname, newname string) *I { return sys.LinkFileType(Process, oldname, newname) } -// LinkFileType appends [HardlinkOp] to [I]. +// LinkFileType maintains a hardlink until its [Enablement] is no longer satisfied. func (sys *I) LinkFileType(et Enablement, oldname, newname string) *I { - sys.ops = append(sys.ops, &HardlinkOp{et, newname, oldname}) + sys.ops = append(sys.ops, &hardlinkOp{et, newname, oldname}) return sys } -// HardlinkOp maintains a hardlink until its [Enablement] is no longer satisfied. -type HardlinkOp struct { +// hardlinkOp implements [I.LinkFileType]. +type hardlinkOp struct { et Enablement dst, src string } -func (l *HardlinkOp) Type() Enablement { return l.et } +func (l *hardlinkOp) Type() Enablement { return l.et } -func (l *HardlinkOp) apply(*I) error { +func (l *hardlinkOp) apply(*I) error { msg.Verbose("linking", l) return newOpError("hardlink", os.Link(l.src, l.dst), false) } -func (l *HardlinkOp) revert(_ *I, ec *Criteria) error { +func (l *hardlinkOp) revert(_ *I, ec *Criteria) error { if ec.hasType(l.Type()) { msg.Verbosef("removing hard link %q", l.dst) return newOpError("hardlink", os.Remove(l.dst), true) @@ -37,10 +37,10 @@ func (l *HardlinkOp) revert(_ *I, ec *Criteria) error { } } -func (l *HardlinkOp) Is(o Op) bool { - target, ok := o.(*HardlinkOp) +func (l *hardlinkOp) Is(o Op) bool { + target, ok := o.(*hardlinkOp) return ok && l != nil && target != nil && *l == *target } -func (l *HardlinkOp) Path() string { return l.src } -func (l *HardlinkOp) String() string { return fmt.Sprintf("%q from %q", l.dst, l.src) } +func (l *hardlinkOp) Path() string { return l.src } +func (l *hardlinkOp) String() string { return fmt.Sprintf("%q from %q", l.dst, l.src) } diff --git a/system/mkdir.go b/system/mkdir.go index 9b92c0f..64b0249 100644 --- a/system/mkdir.go +++ b/system/mkdir.go @@ -6,30 +6,29 @@ import ( "os" ) -// Ensure appends [MkdirOp] to [I] with its [Enablement] ignored. +// Ensure ensures the existence of a directory. func (sys *I) Ensure(name string, perm os.FileMode) *I { - sys.ops = append(sys.ops, &MkdirOp{User, name, perm, false}) + sys.ops = append(sys.ops, &mkdirOp{User, name, perm, false}) return sys } -// Ephemeral appends an ephemeral [MkdirOp] to [I]. +// Ephemeral ensures the existence of a directory until its [Enablement] is no longer satisfied. func (sys *I) Ephemeral(et Enablement, name string, perm os.FileMode) *I { - sys.ops = append(sys.ops, &MkdirOp{et, name, perm, true}) + sys.ops = append(sys.ops, &mkdirOp{et, name, perm, true}) return sys } -// MkdirOp ensures the existence of a directory. -// For ephemeral, the directory is destroyed once [Enablement] is no longer satisfied. -type MkdirOp struct { +// mkdirOp implements [I.Ensure] and [I.Ephemeral]. +type mkdirOp struct { et Enablement path string perm os.FileMode ephemeral bool } -func (m *MkdirOp) Type() Enablement { return m.et } +func (m *mkdirOp) Type() Enablement { return m.et } -func (m *MkdirOp) apply(*I) error { +func (m *mkdirOp) apply(*I) error { msg.Verbose("ensuring directory", m) // create directory @@ -44,7 +43,7 @@ func (m *MkdirOp) apply(*I) error { } } -func (m *MkdirOp) revert(_ *I, ec *Criteria) error { +func (m *mkdirOp) revert(_ *I, ec *Criteria) error { if !m.ephemeral { // skip non-ephemeral dir and do not log anything return nil @@ -59,14 +58,14 @@ func (m *MkdirOp) revert(_ *I, ec *Criteria) error { } } -func (m *MkdirOp) Is(o Op) bool { - target, ok := o.(*MkdirOp) +func (m *mkdirOp) Is(o Op) bool { + target, ok := o.(*mkdirOp) return ok && m != nil && target != nil && *m == *target } -func (m *MkdirOp) Path() string { return m.path } +func (m *mkdirOp) Path() string { return m.path } -func (m *MkdirOp) String() string { +func (m *mkdirOp) String() string { t := "ensure" if m.ephemeral { t = TypeString(m.Type()) diff --git a/system/mkdir_test.go b/system/mkdir_test.go index 8fc12a1..2ead2e1 100644 --- a/system/mkdir_test.go +++ b/system/mkdir_test.go @@ -21,7 +21,7 @@ func TestEnsure(t *testing.T) { t.Run(tc.name+"_"+tc.perm.String(), func(t *testing.T) { sys := New(t.Context(), 150) sys.Ensure(tc.name, tc.perm) - (&tcOp{User, tc.name}).test(t, sys.ops, []Op{&MkdirOp{User, tc.name, tc.perm, false}}, "Ensure") + (&tcOp{User, tc.name}).test(t, sys.ops, []Op{&mkdirOp{User, tc.name, tc.perm, false}}, "Ensure") }) } } @@ -38,7 +38,7 @@ func TestEphemeral(t *testing.T) { t.Run(tc.path+"_"+tc.perm.String()+"_"+TypeString(tc.et), func(t *testing.T) { sys := New(t.Context(), 150) sys.Ephemeral(tc.et, tc.path, tc.perm) - tc.test(t, sys.ops, []Op{&MkdirOp{tc.et, tc.path, tc.perm, true}}, "Ephemeral") + tc.test(t, sys.ops, []Op{&mkdirOp{tc.et, tc.path, tc.perm, true}}, "Ephemeral") }) } } @@ -60,7 +60,7 @@ func TestMkdirString(t *testing.T) { } for _, tc := range testCases { t.Run(tc.want, func(t *testing.T) { - m := &MkdirOp{ + m := &mkdirOp{ et: tc.et, path: container.Nonexistent, perm: 0701, diff --git a/system/tmpfiles.go b/system/tmpfiles.go index 2850ba2..bd865d4 100644 --- a/system/tmpfiles.go +++ b/system/tmpfiles.go @@ -9,16 +9,16 @@ import ( "syscall" ) -// CopyFile appends [TmpfileOp] to [I]. -func (sys *I) CopyFile(payload *[]byte, src string, cap int, n int64) *I { +// CopyFile reads up to n bytes from src and writes the resulting byte slice to payloadP. +func (sys *I) CopyFile(payloadP *[]byte, src string, cap int, n int64) *I { buf := new(bytes.Buffer) buf.Grow(cap) - sys.ops = append(sys.ops, &TmpfileOp{payload, src, n, buf}) + sys.ops = append(sys.ops, &tmpfileOp{payloadP, src, n, buf}) return sys } -// TmpfileOp reads up to n bytes from src and writes the resulting byte slice to payload. -type TmpfileOp struct { +// tmpfileOp implements [I.CopyFile]. +type tmpfileOp struct { payload *[]byte src string @@ -26,8 +26,9 @@ type TmpfileOp struct { buf *bytes.Buffer } -func (t *TmpfileOp) Type() Enablement { return Process } -func (t *TmpfileOp) apply(*I) error { +func (t *tmpfileOp) Type() Enablement { return Process } + +func (t *tmpfileOp) apply(*I) error { msg.Verbose("copying", t) if t.payload == nil { @@ -55,12 +56,12 @@ func (t *TmpfileOp) apply(*I) error { *t.payload = t.buf.Bytes() return nil } -func (t *TmpfileOp) revert(*I, *Criteria) error { t.buf.Reset(); return nil } +func (t *tmpfileOp) revert(*I, *Criteria) error { t.buf.Reset(); return nil } -func (t *TmpfileOp) Is(o Op) bool { - target, ok := o.(*TmpfileOp) +func (t *tmpfileOp) Is(o Op) bool { + target, ok := o.(*tmpfileOp) return ok && t != nil && target != nil && t.src == target.src && t.n == target.n } -func (t *TmpfileOp) Path() string { return t.src } -func (t *TmpfileOp) String() string { return fmt.Sprintf("up to %d bytes from %q", t.n, t.src) } +func (t *tmpfileOp) Path() string { return t.src } +func (t *tmpfileOp) String() string { return fmt.Sprintf("up to %d bytes from %q", t.n, t.src) } diff --git a/system/tmpfiles_test.go b/system/tmpfiles_test.go index 1ed07c6..6410a9a 100644 --- a/system/tmpfiles_test.go +++ b/system/tmpfiles_test.go @@ -18,7 +18,7 @@ func TestCopyFile(t *testing.T) { sys := New(t.Context(), 150) sys.CopyFile(new([]byte), tc.path, tc.cap, tc.n) tc.test(t, sys.ops, []Op{ - &TmpfileOp{nil, tc.path, tc.n, nil}, + &tmpfileOp{nil, tc.path, tc.n, nil}, }, "CopyFile") }) } @@ -36,7 +36,7 @@ func TestLink(t *testing.T) { sys := New(t.Context(), 150) sys.Link(tc.src, tc.dst) (&tcOp{Process, tc.src}).test(t, sys.ops, []Op{ - &HardlinkOp{Process, tc.dst, tc.src}, + &hardlinkOp{Process, tc.dst, tc.src}, }, "Link") }) } @@ -55,7 +55,7 @@ func TestLinkFileType(t *testing.T) { sys := New(t.Context(), 150) sys.LinkFileType(tc.et, tc.path, tc.dst) tc.test(t, sys.ops, []Op{ - &HardlinkOp{tc.et, tc.dst, tc.path}, + &hardlinkOp{tc.et, tc.dst, tc.path}, }, "LinkFileType") }) } @@ -73,7 +73,7 @@ func TestTmpfile_String(t *testing.T) { for _, tc := range testCases { t.Run(tc.want, func(t *testing.T) { - if got := (&TmpfileOp{src: tc.src, n: tc.n}).String(); got != tc.want { + if got := (&tmpfileOp{src: tc.src, n: tc.n}).String(); got != tc.want { t.Errorf("String() = %v, want %v", got, tc.want) } }) diff --git a/system/wayland.go b/system/wayland.go index f6e5051..fac6ee7 100644 --- a/system/wayland.go +++ b/system/wayland.go @@ -9,16 +9,16 @@ import ( "hakurei.app/system/wayland" ) -// Wayland appends [WaylandOp] to [I]. +// Wayland maintains a wayland socket with security-context-v1 attached via [wayland]. +// The socket stops accepting connections once the pipe referred to by sync is closed. +// The socket is pathname only and is destroyed on revert. func (sys *I) Wayland(syncFd **os.File, dst, src, appID, instanceID string) *I { - sys.ops = append(sys.ops, &WaylandOp{syncFd, dst, src, appID, instanceID, wayland.Conn{}}) + sys.ops = append(sys.ops, &waylandOp{syncFd, dst, src, appID, instanceID, wayland.Conn{}}) return sys } -// WaylandOp maintains a wayland socket with security-context-v1 attached via [wayland]. -// The socket stops accepting connections once the pipe referred to by sync is closed. -// The socket is pathname only and is destroyed on revert. -type WaylandOp struct { +// waylandOp implements [I.Wayland]. +type waylandOp struct { sync **os.File dst, src string appID, instanceID string @@ -26,9 +26,9 @@ type WaylandOp struct { conn wayland.Conn } -func (w *WaylandOp) Type() Enablement { return Process } +func (w *waylandOp) Type() Enablement { return Process } -func (w *WaylandOp) apply(sys *I) error { +func (w *waylandOp) apply(sys *I) error { if w.sync == nil { // this is a misuse of the API; do not return a wrapped error return errors.New("invalid sync") @@ -58,7 +58,7 @@ func (w *WaylandOp) apply(sys *I) error { } } -func (w *WaylandOp) revert(_ *I, ec *Criteria) error { +func (w *waylandOp) revert(_ *I, ec *Criteria) error { if ec.hasType(w.Type()) { msg.Verbosef("removing wayland socket on %q", w.dst) if err := os.Remove(w.dst); err != nil && !errors.Is(err, os.ErrNotExist) { @@ -73,12 +73,12 @@ func (w *WaylandOp) revert(_ *I, ec *Criteria) error { } } -func (w *WaylandOp) Is(o Op) bool { - target, ok := o.(*WaylandOp) +func (w *waylandOp) Is(o Op) bool { + target, ok := o.(*waylandOp) return ok && w != nil && target != nil && w.dst == target.dst && w.src == target.src && w.appID == target.appID && w.instanceID == target.instanceID } -func (w *WaylandOp) Path() string { return w.dst } -func (w *WaylandOp) String() string { return fmt.Sprintf("wayland socket at %q", w.dst) } +func (w *waylandOp) Path() string { return w.dst } +func (w *waylandOp) String() string { return fmt.Sprintf("wayland socket at %q", w.dst) } diff --git a/system/xhost.go b/system/xhost.go index 22a0669..cdec129 100644 --- a/system/xhost.go +++ b/system/xhost.go @@ -4,24 +4,24 @@ import ( "hakurei.app/system/internal/xcb" ) -// ChangeHosts appends [XHostOp] to [I]. +// ChangeHosts inserts the target user into X11 hosts and deletes it once its [Enablement] is no longer satisfied. func (sys *I) ChangeHosts(username string) *I { - sys.ops = append(sys.ops, XHostOp(username)) + sys.ops = append(sys.ops, xhostOp(username)) return sys } -// XHostOp inserts the target user into X11 hosts and deletes it once its [Enablement] is no longer satisfied. -type XHostOp string +// xhostOp implements [I.ChangeHosts]. +type xhostOp string -func (x XHostOp) Type() Enablement { return EX11 } +func (x xhostOp) Type() Enablement { return EX11 } -func (x XHostOp) apply(*I) error { +func (x xhostOp) apply(*I) error { msg.Verbosef("inserting entry %s to X11", x) return newOpError("xhost", xcb.ChangeHosts(xcb.HostModeInsert, xcb.FamilyServerInterpreted, "localuser\x00"+string(x)), false) } -func (x XHostOp) revert(_ *I, ec *Criteria) error { +func (x xhostOp) revert(_ *I, ec *Criteria) error { if ec.hasType(x.Type()) { msg.Verbosef("deleting entry %s from X11", x) return newOpError("xhost", @@ -32,6 +32,6 @@ func (x XHostOp) revert(_ *I, ec *Criteria) error { } } -func (x XHostOp) Is(o Op) bool { target, ok := o.(XHostOp); return ok && x == target } -func (x XHostOp) Path() string { return string(x) } -func (x XHostOp) String() string { return string("SI:localuser:" + x) } +func (x xhostOp) Is(o Op) bool { target, ok := o.(xhostOp); return ok && x == target } +func (x xhostOp) Path() string { return string(x) } +func (x xhostOp) String() string { return string("SI:localuser:" + x) } diff --git a/system/xhost_test.go b/system/xhost_test.go index df0e816..32cb063 100644 --- a/system/xhost_test.go +++ b/system/xhost_test.go @@ -11,7 +11,7 @@ func TestChangeHosts(t *testing.T) { sys := New(t.Context(), 150) sys.ChangeHosts(tc) (&tcOp{EX11, tc}).test(t, sys.ops, []Op{ - XHostOp(tc), + xhostOp(tc), }, "ChangeHosts") }) } @@ -26,7 +26,7 @@ func TestXHost_String(t *testing.T) { } for _, tc := range testCases { t.Run(tc.want, func(t *testing.T) { - if got := XHostOp(tc.username).String(); got != tc.want { + if got := xhostOp(tc.username).String(); got != tc.want { t.Errorf("String() = %v, want %v", got, tc.want) } })