aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/state
diff options
context:
space:
mode:
Diffstat (limited to 'internal/state')
-rw-r--r--internal/state/data.go51
-rw-r--r--internal/state/exit.go73
-rw-r--r--internal/state/print.go61
-rw-r--r--internal/state/register.go35
-rw-r--r--internal/state/track.go64
-rw-r--r--internal/state/value.go21
6 files changed, 73 insertions, 232 deletions
diff --git a/internal/state/data.go b/internal/state/data.go
new file mode 100644
index 00000000..65b6395e
--- /dev/null
+++ b/internal/state/data.go
@@ -0,0 +1,51 @@
+package state
+
+import (
+ "encoding/gob"
+ "os"
+ "path"
+)
+
+// we unfortunately have to assume there are never races between processes
+// this and launcher should eventually be replaced by a server process
+
+type launcherState struct {
+ PID int
+ Launcher string
+ Argv []string
+ Command []string
+ Capability Enablements
+}
+
+func ReadLaunchers(runDirPath, uid string) ([]*launcherState, error) {
+ var f *os.File
+ var r []*launcherState
+ launcherPrefix := path.Join(runDirPath, uid)
+
+ if pl, err := os.ReadDir(launcherPrefix); err != nil {
+ return nil, err
+ } else {
+ for _, e := range pl {
+ if err = func() error {
+ if f, err = os.Open(path.Join(launcherPrefix, e.Name())); err != nil {
+ return err
+ } else {
+ defer func() {
+ if f.Close() != nil {
+ // unreachable
+ panic("foreign state file closed prematurely")
+ }
+ }()
+
+ var s launcherState
+ r = append(r, &s)
+ return gob.NewDecoder(f).Decode(&s)
+ }
+ }(); err != nil {
+ return nil, err
+ }
+ }
+ }
+
+ return r, nil
+}
diff --git a/internal/state/exit.go b/internal/state/exit.go
deleted file mode 100644
index 0eb80a83..00000000
--- a/internal/state/exit.go
+++ /dev/null
@@ -1,73 +0,0 @@
-package state
-
-import (
- "errors"
- "fmt"
- "io/fs"
- "os"
-
- "git.ophivana.moe/cat/fortify/internal/acl"
- "git.ophivana.moe/cat/fortify/internal/verbose"
- "git.ophivana.moe/cat/fortify/internal/xcb"
-)
-
-func Fatal(msg ...any) {
- fmt.Println(msg...)
- BeforeExit()
- os.Exit(1)
-}
-
-func BeforeExit() {
- if u == nil {
- fmt.Println("warn: beforeExit called before app init")
- return
- }
-
- if statePath == "" {
- verbose.Println("State path is unset")
- } else {
- if err := os.Remove(statePath); err != nil && !errors.Is(err, fs.ErrNotExist) {
- fmt.Println("Error removing state file:", err)
- }
- }
-
- if d, err := readLaunchers(u.Uid); err != nil {
- fmt.Println("Error reading active launchers:", err)
- os.Exit(1)
- } else if len(d) > 0 {
- // other launchers are still active
- verbose.Printf("Found %d active launchers, exiting without cleaning up\n", len(d))
- return
- }
-
- verbose.Println("No other launchers active, will clean up")
-
- if xcbActionComplete {
- verbose.Printf("X11: Removing XHost entry SI:localuser:%s\n", u.Username)
- if err := xcb.ChangeHosts(xcb.HostModeDelete, xcb.FamilyServerInterpreted, "localuser\x00"+u.Username); err != nil {
- fmt.Println("Error removing XHost entry:", err)
- }
- }
-
- for _, candidate := range cleanupCandidate {
- if err := acl.UpdatePerm(candidate, uid); err != nil {
- fmt.Printf("Error stripping ACL entry from '%s': %s\n", candidate, err)
- }
- verbose.Printf("Stripped ACL entry for user '%s' from '%s'\n", u.Username, candidate)
- }
-
- if dbusProxy != nil {
- verbose.Println("D-Bus proxy registered, cleaning up")
-
- if err := dbusProxy.Close(); err != nil {
- if errors.Is(err, os.ErrClosed) {
- verbose.Println("D-Bus proxy already closed")
- } else {
- fmt.Println("Error closing D-Bus proxy:", err)
- }
- }
-
- // wait for Proxy.Wait to return
- <-*dbusDone
- }
-}
diff --git a/internal/state/print.go b/internal/state/print.go
index 0881f199..83912d32 100644
--- a/internal/state/print.go
+++ b/internal/state/print.go
@@ -1,68 +1,37 @@
package state
import (
- "flag"
"fmt"
"os"
"strconv"
"strings"
"text/tabwriter"
- "git.ophivana.moe/cat/fortify/internal/system"
"git.ophivana.moe/cat/fortify/internal/verbose"
)
-var (
- stateActionEarly bool
- stateActionEarlyC bool
-)
-
-func init() {
- flag.BoolVar(&stateActionEarly, "state", false, "print state information of active launchers")
- flag.BoolVar(&stateActionEarlyC, "state-current", false, "print state information of active launchers for the specified user")
-}
-
-func Early() {
- var w *tabwriter.Writer
-
- switch {
- case stateActionEarly:
- if runDir, err := os.ReadDir(system.V.RunDir); err != nil {
- fmt.Println("Error reading runtime directory:", err)
- } else {
- for _, e := range runDir {
- if !e.IsDir() {
- verbose.Println("Skipped non-directory entry", e.Name())
- continue
- }
-
- if _, err = strconv.Atoi(e.Name()); err != nil {
- verbose.Println("Skipped non-uid entry", e.Name())
- continue
- }
+func MustPrintLauncherStateGlobal(w **tabwriter.Writer, runDirPath string) {
+ if dirs, err := os.ReadDir(runDirPath); err != nil {
+ fmt.Println("Error reading runtime directory:", err)
+ } else {
+ for _, e := range dirs {
+ if !e.IsDir() {
+ verbose.Println("Skipped non-directory entry", e.Name())
+ continue
+ }
- printLauncherState(e.Name(), &w)
+ if _, err = strconv.Atoi(e.Name()); err != nil {
+ verbose.Println("Skipped non-uid entry", e.Name())
+ continue
}
- }
- case stateActionEarlyC:
- printLauncherState(u.Uid, &w)
- default:
- return
- }
- if w != nil {
- if err := w.Flush(); err != nil {
- fmt.Println("warn: error formatting output:", err)
+ MustPrintLauncherState(w, runDirPath, e.Name())
}
- } else {
- fmt.Println("No information available.")
}
-
- os.Exit(0)
}
-func printLauncherState(uid string, w **tabwriter.Writer) {
- launchers, err := readLaunchers(uid)
+func MustPrintLauncherState(w **tabwriter.Writer, runDirPath, uid string) {
+ launchers, err := ReadLaunchers(runDirPath, uid)
if err != nil {
fmt.Println("Error reading launchers:", err)
os.Exit(1)
diff --git a/internal/state/register.go b/internal/state/register.go
deleted file mode 100644
index be9ce540..00000000
--- a/internal/state/register.go
+++ /dev/null
@@ -1,35 +0,0 @@
-package state
-
-import "git.ophivana.moe/cat/fortify/dbus"
-
-var (
- cleanupCandidate []string
- enablements *Enablements
- xcbActionComplete bool
-
- dbusProxy *dbus.Proxy
- dbusDone *chan struct{}
-)
-
-func RegisterRevertPath(p string) {
- cleanupCandidate = append(cleanupCandidate, p)
-}
-
-func RegisterEnablement(e Enablements) {
- if enablements != nil {
- panic("enablement state set twice")
- }
- enablements = &e
-}
-
-func XcbActionComplete() {
- if xcbActionComplete {
- Fatal("xcb inserted twice")
- }
- xcbActionComplete = true
-}
-
-func RegisterDBus(p *dbus.Proxy, done *chan struct{}) {
- dbusProxy = p
- dbusDone = done
-}
diff --git a/internal/state/track.go b/internal/state/track.go
index 198abebf..308be28a 100644
--- a/internal/state/track.go
+++ b/internal/state/track.go
@@ -8,42 +8,25 @@ import (
"os/exec"
"path"
"strconv"
-
- "git.ophivana.moe/cat/fortify/internal/system"
-)
-
-// we unfortunately have to assume there are never races between processes
-// this and launcher should eventually be replaced by a server process
-
-var (
- statePath string
)
-type launcherState struct {
- PID int
- Launcher string
- Argv []string
- Command []string
- Capability Enablements
-}
-
// SaveProcess called after process start, before wait
-func SaveProcess(uid string, cmd *exec.Cmd) error {
- statePath = path.Join(system.V.RunDir, uid, strconv.Itoa(cmd.Process.Pid))
+func SaveProcess(uid string, cmd *exec.Cmd, runDirPath string, command []string, enablements Enablements) (string, error) {
+ statePath := path.Join(runDirPath, uid, strconv.Itoa(cmd.Process.Pid))
state := launcherState{
PID: cmd.Process.Pid,
Launcher: cmd.Path,
Argv: cmd.Args,
Command: command,
- Capability: *enablements,
+ Capability: enablements,
}
- if err := os.Mkdir(path.Join(system.V.RunDir, uid), 0700); err != nil && !errors.Is(err, fs.ErrExist) {
- return err
+ if err := os.Mkdir(path.Join(runDirPath, uid), 0700); err != nil && !errors.Is(err, fs.ErrExist) {
+ return statePath, err
}
if f, err := os.OpenFile(statePath, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600); err != nil {
- return err
+ return statePath, err
} else {
defer func() {
if f.Close() != nil {
@@ -51,39 +34,6 @@ func SaveProcess(uid string, cmd *exec.Cmd) error {
panic("state file closed prematurely")
}
}()
- return gob.NewEncoder(f).Encode(state)
- }
-}
-
-func readLaunchers(uid string) ([]*launcherState, error) {
- var f *os.File
- var r []*launcherState
- launcherPrefix := path.Join(system.V.RunDir, uid)
-
- if pl, err := os.ReadDir(launcherPrefix); err != nil {
- return nil, err
- } else {
- for _, e := range pl {
- if err = func() error {
- if f, err = os.Open(path.Join(launcherPrefix, e.Name())); err != nil {
- return err
- } else {
- defer func() {
- if f.Close() != nil {
- // unreachable
- panic("foreign state file closed prematurely")
- }
- }()
-
- var s launcherState
- r = append(r, &s)
- return gob.NewDecoder(f).Decode(&s)
- }
- }(); err != nil {
- return nil, err
- }
- }
+ return statePath, gob.NewEncoder(f).Encode(state)
}
-
- return r, nil
}
diff --git a/internal/state/value.go b/internal/state/value.go
deleted file mode 100644
index cb20818c..00000000
--- a/internal/state/value.go
+++ /dev/null
@@ -1,21 +0,0 @@
-package state
-
-import (
- "os/user"
-)
-
-var (
- u *user.User
- uid int
- command []string
-)
-
-func Set(val user.User, c []string, d int) {
- if u != nil {
- panic("state set twice")
- }
-
- u = &val
- command = c
- uid = d
-}