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) } })